diff --git a/lib/fs.js b/lib/fs.js index db262f5da8fc22..ab9cd614a4a02f 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -341,7 +341,7 @@ Stats.prototype.isSocket = function() { return this._checkModeProperty(S_IFSOCK); }; -const statValues = binding.getStatValues(); +const statValues = binding.statValues; function statsFromValues() { return new Stats(statValues[0], statValues[1], statValues[2], statValues[3], diff --git a/src/env-inl.h b/src/env-inl.h index 910bba69f7569f..4a6e73cc38807e 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -322,7 +322,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_(isolate_, kFsStatsFieldsLength), context_(context->GetIsolate(), context) { // We'll be creating new objects so make sure we've entered the context. v8::HandleScope handle_scope(isolate()); @@ -547,13 +547,9 @@ inline void Environment::set_http2_state( http2_state_ = std::move(buffer); } -inline double* Environment::fs_stats_field_array() const { - return 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 AliasedBuffer* +Environment::fs_stats_field_array() { + return &fs_stats_field_array_; } void Environment::CreateImmediate(native_immediate_callback cb, diff --git a/src/env.h b/src/env.h index f5a11dca07a20b..a1f505c4fe1da1 100644 --- a/src/env.h +++ b/src/env.h @@ -610,8 +610,7 @@ class Environment { inline http2::http2_state* http2_state() const; inline void set_http2_state(std::unique_ptr state); - inline double* fs_stats_field_array() const; - inline void set_fs_stats_field_array(double* fields); + inline AliasedBuffer* fs_stats_field_array(); inline performance::performance_state* performance_state(); inline std::map* performance_marks(); @@ -778,7 +777,10 @@ class Environment { char* http_parser_buffer_; std::unique_ptr http2_state_; - double* fs_stats_field_array_; + // stat fields contains twice the number of entries because `fs.StatWatcher` + // needs room to store data for *two* `fs.Stats` instances. + static const int kFsStatsFieldsLength = 2 * 14; + AliasedBuffer fs_stats_field_array_; struct BeforeExitCallback { void (*cb_)(void* arg); diff --git a/src/node_file.cc b/src/node_file.cc index e6b1116e9924b8..8cbfa1b1793269 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -19,6 +19,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. +#include "aliased_buffer.h" #include "node_buffer.h" #include "node_internals.h" #include "node_stat_watcher.h" @@ -44,32 +45,34 @@ namespace node { -void FillStatsArray(double* fields, const uv_stat_t* s) { - fields[0] = s->st_dev; - fields[1] = s->st_mode; - fields[2] = s->st_nlink; - fields[3] = s->st_uid; - fields[4] = s->st_gid; - fields[5] = s->st_rdev; +void FillStatsArray(AliasedBuffer* fields_ptr, + const uv_stat_t* s, int offset) { + AliasedBuffer& fields = *fields_ptr; + fields[offset + 0] = s->st_dev; + fields[offset + 1] = s->st_mode; + fields[offset + 2] = s->st_nlink; + fields[offset + 3] = s->st_uid; + fields[offset + 4] = s->st_gid; + fields[offset + 5] = s->st_rdev; #if defined(__POSIX__) - fields[6] = s->st_blksize; + fields[offset + 6] = s->st_blksize; #else - fields[6] = -1; + fields[offset + 6] = -1; #endif - fields[7] = s->st_ino; - fields[8] = s->st_size; + fields[offset + 7] = s->st_ino; + fields[offset + 8] = s->st_size; #if defined(__POSIX__) - fields[9] = s->st_blocks; + fields[offset + 9] = s->st_blocks; #else - fields[9] = -1; + fields[offset + 9] = -1; #endif // Dates. // NO-LINT because the fields are 'long' and we just want to cast to `unsigned` -#define X(idx, name) \ - /* NOLINTNEXTLINE(runtime/int) */ \ - fields[idx] = ((unsigned long)(s->st_##name.tv_sec) * 1e3) + \ - /* NOLINTNEXTLINE(runtime/int) */ \ - ((unsigned long)(s->st_##name.tv_nsec) / 1e6); \ +#define X(idx, name) \ + /* NOLINTNEXTLINE(runtime/int) */ \ + fields[offset + idx] = ((unsigned long)(s->st_##name.tv_sec) * 1e3) + \ + /* NOLINTNEXTLINE(runtime/int) */ \ + ((unsigned long)(s->st_##name.tv_nsec) / 1e6); \ X(10, atim) X(11, mtim) @@ -81,7 +84,6 @@ void FillStatsArray(double* fields, const uv_stat_t* s) { namespace fs { using v8::Array; -using v8::ArrayBuffer; using v8::Context; using v8::Float64Array; using v8::Function; @@ -1295,22 +1297,6 @@ 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) { - // 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]; - 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); -} - void InitFs(Local target, Local unused, Local context, @@ -1356,7 +1342,9 @@ void InitFs(Local target, env->SetMethod(target, "mkdtemp", Mkdtemp); - env->SetMethod(target, "getStatValues", GetStatValues); + target->Set(context, + FIXED_ONE_BYTE_STRING(env->isolate(), "statValues"), + env->fs_stats_field_array()->GetJSArray()).FromJust(); StatWatcher::Initialize(env, target); diff --git a/src/node_internals.h b/src/node_internals.h index bb03d490f83067..0f693527cceeb1 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -292,7 +292,8 @@ v8::Maybe ProcessEmitDeprecationWarning(Environment* env, const char* warning, const char* deprecation_code); -void FillStatsArray(double* fields, const uv_stat_t* s); +void FillStatsArray(AliasedBuffer* fields_ptr, + 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 9aa0c950591d16..00b43f6eb7c102 100644 --- a/src/node_stat_watcher.cc +++ b/src/node_stat_watcher.cc @@ -89,7 +89,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); }