diff --git a/deps/chakrashim/include/v8.h b/deps/chakrashim/include/v8.h index 4ed31b5a1d5..cb47aa9d407 100644 --- a/deps/chakrashim/include/v8.h +++ b/deps/chakrashim/include/v8.h @@ -533,6 +533,7 @@ class PersistentBase { private: template friend class Local; + template friend class Global; template friend class Persistent; explicit V8_INLINE PersistentBase(T* val) diff --git a/src/env-inl.h b/src/env-inl.h index 978f8ca819d..b7c6fb4f4b4 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -199,7 +199,7 @@ inline Environment::Environment(IsolateData* isolate_data, #endif handle_cleanup_waiting_(0), http_parser_buffer_(nullptr), - fs_stats_field_array_(nullptr), + fs_stats_field_array_(), context_(context->GetIsolate(), context) { // We'll be creating new objects so make sure we've entered the context. v8::HandleScope handle_scope(isolate()); @@ -245,6 +245,8 @@ inline Environment::~Environment() { while (handle_cleanup_waiting_ != 0) uv_run(event_loop(), UV_RUN_ONCE); + fs_stats_field_array_.Empty(); + context()->SetAlignedPointerInEmbedderData(kContextEmbedderDataIndex, nullptr); #define V(PropertyName, TypeName) PropertyName ## _.Reset(); @@ -381,13 +383,13 @@ inline void Environment::set_http_parser_buffer(char* buffer) { http_parser_buffer_ = buffer; } -inline double* Environment::fs_stats_field_array() const { - return fs_stats_field_array_; +inline v8::Local Environment::fs_stats_field_array() const { + return v8::Local::New(isolate_, fs_stats_field_array_); } -inline void Environment::set_fs_stats_field_array(double* fields) { - CHECK_EQ(fs_stats_field_array_, nullptr); // Should be set only once. - fs_stats_field_array_ = fields; +inline void Environment::set_fs_stats_field_array(v8::Local fields) { + CHECK_EQ(fs_stats_field_array_.IsEmpty(), true); // Should be set only once. + fs_stats_field_array_ = v8::Global::Global(isolate_, fields); } inline Environment* Environment::from_cares_timer_handle(uv_timer_t* handle) { diff --git a/src/env.h b/src/env.h index abb0e6d0e5a..76056228e8b 100644 --- a/src/env.h +++ b/src/env.h @@ -491,8 +491,8 @@ class Environment { inline char* http_parser_buffer() const; inline void set_http_parser_buffer(char* buffer); - inline double* fs_stats_field_array() const; - inline void set_fs_stats_field_array(double* fields); + inline v8::Local fs_stats_field_array() const; + inline void set_fs_stats_field_array(v8::Local fields); inline void ThrowError(const char* errmsg); inline void ThrowTypeError(const char* errmsg); @@ -602,7 +602,8 @@ class Environment { char* http_parser_buffer_; - double* fs_stats_field_array_; + //We depend on the property in fs.js to manage the lifetime appropriately + v8::Global fs_stats_field_array_; #define V(PropertyName, TypeName) \ v8::Persistent PropertyName ## _; diff --git a/src/node_file.cc b/src/node_file.cc index 05e48de35cd..c4bb422b806 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -448,7 +448,10 @@ static void Close(const FunctionCallbackInfo& args) { } -void FillStatsArray(double* fields, const uv_stat_t* s) { +void FillStatsArray(v8::Local fields_array, const uv_stat_t* s, int offset) { + Local ab = fields_array->Buffer(); + double* fields = static_cast(ab->GetContents().Data()) + offset; + fields[0] = s->st_dev; fields[1] = s->st_mode; fields[2] = s->st_nlink; @@ -477,6 +480,12 @@ void FillStatsArray(double* fields, const uv_stat_t* s) { X(12, ctim) X(13, birthtim) #undef X + +#if ENABLE_TTD_NODE + if(s_doTTRecord || s_doTTReplay) { + ab->TTDRawBufferModifyNotifySync(offset * sizeof(double), 14 * sizeof(double)); + } +#endif } // Used to speed up module loading. Returns the contents of the file as @@ -1392,18 +1401,20 @@ static void Mkdtemp(const FunctionCallbackInfo& args) { void GetStatValues(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - double* fields = env->fs_stats_field_array(); - if (fields == nullptr) { + Local fields = env->fs_stats_field_array(); + + if (fields.IsEmpty()) { // stat fields contains twice the number of entries because `fs.StatWatcher` // needs room to store data for *two* `fs.Stats` instances. - fields = new double[2 * 14]; + Local ab = ArrayBuffer::New(env->isolate(), + new double[2 * 14], + sizeof(double) * 2 * 14); + fields = Float64Array::New(ab, 0, 2 * 14); + env->set_fs_stats_field_array(fields); } - Local ab = ArrayBuffer::New(env->isolate(), - fields, - sizeof(double) * 2 * 14); - Local fields_array = Float64Array::New(ab, 0, 2 * 14); - args.GetReturnValue().Set(fields_array); + + args.GetReturnValue().Set(fields); } void InitFs(Local target, diff --git a/src/node_internals.h b/src/node_internals.h index 0ee694a2284..7262d0f0d5d 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -162,7 +162,7 @@ NO_RETURN void FatalError(const char* location, const char* message); void ProcessEmitWarning(Environment* env, const char* fmt, ...); -void FillStatsArray(double* fields, const uv_stat_t* s); +void FillStatsArray(v8::Local fields_array, const uv_stat_t* s, int offset = 0); void SetupProcessObject(Environment* env, int argc, diff --git a/src/node_stat_watcher.cc b/src/node_stat_watcher.cc index 9eeed77476b..4c81f3af539 100644 --- a/src/node_stat_watcher.cc +++ b/src/node_stat_watcher.cc @@ -88,7 +88,7 @@ void StatWatcher::Callback(uv_fs_poll_t* handle, Context::Scope context_scope(env->context()); FillStatsArray(env->fs_stats_field_array(), curr); - FillStatsArray(env->fs_stats_field_array() + 14, prev); + FillStatsArray(env->fs_stats_field_array(), prev, 14); Local arg = Integer::New(env->isolate(), status); wrap->MakeCallback(env->onchange_string(), 1, &arg); }