| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 88b57bc commit 3a4f387
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -162,6 +162,9 @@ const rawMethods = internalBinding('process_methods'); | |||
| 162 | 162 | process.kill = wrapped.kill; | |
| 163 | 163 | process.exit = wrapped.exit; | |
| 164 | 164 | ||
| 165 | + process.hrtime = perThreadSetup.hrtime; | ||
| 166 | + process.hrtime.bigint = perThreadSetup.hrtimeBigInt; | ||
| 167 | + | ||
| 165 | 168 | process.openStdin = function() { | |
| 166 | 169 | process.stdin.resume(); | |
| 167 | 170 | return process.stdin; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -82,16 +82,7 @@ function patchProcessObject(expandArgv1) { | |||
| 82 | 82 | const binding = internalBinding('process_methods'); | |
| 83 | 83 | binding.patchProcessObject(process); | |
| 84 | 84 | ||
| 85 | - // TODO(joyeecheung): snapshot fast APIs (which need to work with | ||
| 86 | - // array buffers, whose connection with C++ needs to be rebuilt after | ||
| 87 | - // deserialization). | ||
| 88 | - const { | ||
| 89 | - hrtime, | ||
| 90 | - hrtimeBigInt | ||
| 91 | - } = require('internal/process/per_thread').getFastAPIs(binding); | ||
| 92 | - | ||
| 93 | - process.hrtime = hrtime; | ||
| 94 | - process.hrtime.bigint = hrtimeBigInt; | ||
| 85 | + require('internal/process/per_thread').refreshHrtimeBuffer(); | ||
| 95 | 86 | ||
| 96 | 87 | ObjectDefineProperty(process, 'argv0', { | |
| 97 | 88 | enumerable: true, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -54,49 +54,48 @@ function assert(x, msg) { | |||
| 54 | 54 | if (!x) throw new ERR_ASSERTION(msg || 'assertion error'); | |
| 55 | 55 | } | |
| 56 | 56 | ||
| 57 | - function getFastAPIs(binding) { | ||
| 58 | - const { | ||
| 59 | - hrtime: _hrtime | ||
| 60 | - } = binding.getFastAPIs(); | ||
| 57 | + const binding = internalBinding('process_methods'); | ||
| 58 | + | ||
| 59 | + let hrValues; | ||
| 60 | + let hrBigintValues; | ||
| 61 | 61 | ||
| 62 | + function refreshHrtimeBuffer() { | ||
| 62 | 63 | // The 3 entries filled in by the original process.hrtime contains | |
| 63 | 64 | // the upper/lower 32 bits of the second part of the value, | |
| 64 | 65 | // and the remaining nanoseconds of the value. | |
| 65 | - const hrValues = new Uint32Array(_hrtime.buffer); | ||
| 66 | + hrValues = new Uint32Array(binding.hrtimeBuffer); | ||
| 67 | + // Use a BigUint64Array in the closure because this is actually a bit | ||
| 68 | + // faster than simply returning a BigInt from C++ in V8 7.1. | ||
| 69 | + hrBigintValues = new BigUint64Array(binding.hrtimeBuffer, 0, 1); | ||
| 70 | + } | ||
| 66 | 71 | ||
| 67 | - function hrtime(time) { | ||
| 68 | - _hrtime.hrtime(); | ||
| 72 | + // Create the buffers. | ||
| 73 | + refreshHrtimeBuffer(); | ||
| 69 | 74 | ||
| 70 | - if (time !== undefined) { | ||
| 71 | - validateArray(time, 'time'); | ||
| 72 | - if (time.length !== 2) { | ||
| 73 | - throw new ERR_OUT_OF_RANGE('time', 2, time.length); | ||
| 74 | - } | ||
| 75 | + function hrtime(time) { | ||
| 76 | + binding.hrtime(); | ||
| 75 | 77 | ||
| 76 | - const sec = (hrValues[0] * 0x100000000 + hrValues[1]) - time[0]; | ||
| 77 | - const nsec = hrValues[2] - time[1]; | ||
| 78 | - const needsBorrow = nsec < 0; | ||
| 79 | - return [needsBorrow ? sec - 1 : sec, needsBorrow ? nsec + 1e9 : nsec]; | ||
| 78 | + if (time !== undefined) { | ||
| 79 | + validateArray(time, 'time'); | ||
| 80 | + if (time.length !== 2) { | ||
| 81 | + throw new ERR_OUT_OF_RANGE('time', 2, time.length); | ||
| 80 | 82 | } | |
| 81 | 83 | ||
| 82 | - return [ | ||
| 83 | - hrValues[0] * 0x100000000 + hrValues[1], | ||
| 84 | - hrValues[2], | ||
| 85 | - ]; | ||
| 84 | + const sec = (hrValues[0] * 0x100000000 + hrValues[1]) - time[0]; | ||
| 85 | + const nsec = hrValues[2] - time[1]; | ||
| 86 | + const needsBorrow = nsec < 0; | ||
| 87 | + return [needsBorrow ? sec - 1 : sec, needsBorrow ? nsec + 1e9 : nsec]; | ||
| 86 | 88 | } | |
| 87 | 89 | ||
| 88 | - // Use a BigUint64Array in the closure because this is actually a bit | ||
| 89 | - // faster than simply returning a BigInt from C++ in V8 7.1. | ||
| 90 | - const hrBigintValues = new BigUint64Array(_hrtime.buffer, 0, 1); | ||
| 91 | - function hrtimeBigInt() { | ||
| 92 | - _hrtime.hrtimeBigInt(); | ||
| 93 | - return hrBigintValues[0]; | ||
| 94 | - } | ||
| 90 | + return [ | ||
| 91 | + hrValues[0] * 0x100000000 + hrValues[1], | ||
| 92 | + hrValues[2], | ||
| 93 | + ]; | ||
| 94 | + } | ||
| 95 | 95 | ||
| 96 | - return { | ||
| 97 | - hrtime, | ||
| 98 | - hrtimeBigInt, | ||
| 99 | - }; | ||
| 96 | + function hrtimeBigInt() { | ||
| 97 | + binding.hrtimeBigInt(); | ||
| 98 | + return hrBigintValues[0]; | ||
| 100 | 99 | } | |
| 101 | 100 | ||
| 102 | 101 | // The execution of this function itself should not cause any side effects. | |
@@ -396,8 +395,10 @@ function toggleTraceCategoryState(asyncHooksEnabled) { | |||
| 396 | 395 | ||
| 397 | 396 | module.exports = { | |
| 398 | 397 | toggleTraceCategoryState, | |
| 399 | - getFastAPIs, | ||
| 400 | 398 | assert, | |
| 401 | 399 | buildAllowedFlags, | |
| 402 | - wrapProcessMethods | ||
| 400 | + wrapProcessMethods, | ||
| 401 | + hrtime, | ||
| 402 | + hrtimeBigInt, | ||
| 403 | + refreshHrtimeBuffer, | ||
| 403 | 404 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -29,11 +29,12 @@ | |||
| 29 | 29 | #include "callback_queue-inl.h" | |
| 30 | 30 | #include "env.h" | |
| 31 | 31 | #include "node.h" | |
| 32 | + #include "node_context_data.h" | ||
| 33 | + #include "node_perf_common.h" | ||
| 32 | 34 | #include "util-inl.h" | |
| 33 | 35 | #include "uv.h" | |
| 36 | + #include "v8-fast-api-calls.h" | ||
| 34 | 37 | #include "v8.h" | |
| 35 | - #include "node_perf_common.h" | ||
| 36 | - #include "node_context_data.h" | ||
| 37 | 38 | ||
| 38 | 39 | #include <cstddef> | |
| 39 | 40 | #include <cstdint> | |
@@ -1036,13 +1037,20 @@ inline void Environment::ThrowUVException(int errorno, | |||
| 1036 | 1037 | UVException(isolate(), errorno, syscall, message, path, dest)); | |
| 1037 | 1038 | } | |
| 1038 | 1039 | ||
| 1039 | - inline v8::Local<v8::FunctionTemplate> | ||
| 1040 | - Environment::NewFunctionTemplate(v8::FunctionCallback callback, | ||
| 1041 | - v8::Local<v8::Signature> signature, | ||
| 1042 | - v8::ConstructorBehavior behavior, | ||
| 1043 | - v8::SideEffectType side_effect_type) { | ||
| 1044 | - return v8::FunctionTemplate::New(isolate(), callback, v8::Local<v8::Value>(), | ||
| 1045 | - signature, 0, behavior, side_effect_type); | ||
| 1040 | + inline v8::Local<v8::FunctionTemplate> Environment::NewFunctionTemplate( | ||
| 1041 | + v8::FunctionCallback callback, | ||
| 1042 | + v8::Local<v8::Signature> signature, | ||
| 1043 | + v8::ConstructorBehavior behavior, | ||
| 1044 | + v8::SideEffectType side_effect_type, | ||
| 1045 | + const v8::CFunction* c_function) { | ||
| 1046 | + return v8::FunctionTemplate::New(isolate(), | ||
| 1047 | + callback, | ||
| 1048 | + v8::Local<v8::Value>(), | ||
| 1049 | + signature, | ||
| 1050 | + 0, | ||
| 1051 | + behavior, | ||
| 1052 | + side_effect_type, | ||
| 1053 | + c_function); | ||
| 1046 | 1054 | } | |
| 1047 | 1055 | ||
| 1048 | 1056 | inline void Environment::SetMethod(v8::Local<v8::Object> that, | |
@@ -1063,6 +1071,25 @@ inline void Environment::SetMethod(v8::Local<v8::Object> that, | |||
| 1063 | 1071 | function->SetName(name_string); // NODE_SET_METHOD() compatibility. | |
| 1064 | 1072 | } | |
| 1065 | 1073 | ||
| 1074 | + inline void Environment::SetFastMethod(v8::Local<v8::Object> that, | ||
| 1075 | + const char* name, | ||
| 1076 | + v8::FunctionCallback slow_callback, | ||
| 1077 | + const v8::CFunction* c_function) { | ||
| 1078 | + v8::Local<v8::Context> context = isolate()->GetCurrentContext(); | ||
| 1079 | + v8::Local<v8::Function> function = | ||
| 1080 | + NewFunctionTemplate(slow_callback, | ||
| 1081 | + v8::Local<v8::Signature>(), | ||
| 1082 | + v8::ConstructorBehavior::kThrow, | ||
| 1083 | + v8::SideEffectType::kHasNoSideEffect, | ||
| 1084 | + c_function) | ||
| 1085 | + ->GetFunction(context) | ||
| 1086 | + .ToLocalChecked(); | ||
| 1087 | + const v8::NewStringType type = v8::NewStringType::kInternalized; | ||
| 1088 | + v8::Local<v8::String> name_string = | ||
| 1089 | + v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); | ||
| 1090 | + that->Set(context, name_string, function).Check(); | ||
| 1091 | + } | ||
| 1092 | + | ||
| 1066 | 1093 | inline void Environment::SetMethodNoSideEffect(v8::Local<v8::Object> that, | |
| 1067 | 1094 | const char* name, | |
| 1068 | 1095 | v8::FunctionCallback callback) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -34,6 +34,7 @@ | |||
| 34 | 34 | #include "handle_wrap.h" | |
| 35 | 35 | #include "node.h" | |
| 36 | 36 | #include "node_binding.h" | |
| 37 | + #include "node_external_reference.h" | ||
| 37 | 38 | #include "node_main_instance.h" | |
| 38 | 39 | #include "node_options.h" | |
| 39 | 40 | #include "node_perf_common.h" | |
@@ -1239,20 +1240,23 @@ class Environment : public MemoryRetainer { | |||
| 1239 | 1240 | const char* path = nullptr, | |
| 1240 | 1241 | const char* dest = nullptr); | |
| 1241 | 1242 | ||
| 1242 | - inline v8::Local<v8::FunctionTemplate> | ||
| 1243 | - NewFunctionTemplate(v8::FunctionCallback callback, | ||
| 1244 | - v8::Local<v8::Signature> signature = | ||
| 1245 | - v8::Local<v8::Signature>(), | ||
| 1246 | - v8::ConstructorBehavior behavior = | ||
| 1247 | - v8::ConstructorBehavior::kAllow, | ||
| 1248 | - v8::SideEffectType side_effect = | ||
| 1249 | - v8::SideEffectType::kHasSideEffect); | ||
| 1243 | + inline v8::Local<v8::FunctionTemplate> NewFunctionTemplate( | ||
| 1244 | + v8::FunctionCallback callback, | ||
| 1245 | + v8::Local<v8::Signature> signature = v8::Local<v8::Signature>(), | ||
| 1246 | + v8::ConstructorBehavior behavior = v8::ConstructorBehavior::kAllow, | ||
| 1247 | + v8::SideEffectType side_effect = v8::SideEffectType::kHasSideEffect, | ||
| 1248 | + const v8::CFunction* c_function = nullptr); | ||
| 1250 | 1249 | ||
| 1251 | 1250 | // Convenience methods for NewFunctionTemplate(). | |
| 1252 | 1251 | inline void SetMethod(v8::Local<v8::Object> that, | |
| 1253 | 1252 | const char* name, | |
| 1254 | 1253 | v8::FunctionCallback callback); | |
| 1255 | 1254 | ||
| 1255 | + inline void SetFastMethod(v8::Local<v8::Object> that, | ||
| 1256 | + const char* name, | ||
| 1257 | + v8::FunctionCallback slow_callback, | ||
| 1258 | + const v8::CFunction* c_function); | ||
| 1259 | + | ||
| 1256 | 1260 | inline void SetProtoMethod(v8::Local<v8::FunctionTemplate> that, | |
| 1257 | 1261 | const char* name, | |
| 1258 | 1262 | v8::FunctionCallback callback); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,17 +5,22 @@ | |||
| 5 | 5 | ||
| 6 | 6 | #include <cinttypes> | |
| 7 | 7 | #include <vector> | |
| 8 | + #include "v8-fast-api-calls.h" | ||
| 8 | 9 | #include "v8.h" | |
| 9 | 10 | ||
| 10 | 11 | namespace node { | |
| 11 | 12 | ||
| 13 | + using CFunctionCallback = void (*)(v8::Local<v8::Value> receiver); | ||
| 14 | + | ||
| 12 | 15 | // This class manages the external references from the V8 heap | |
| 13 | 16 | // to the C++ addresses in Node.js. | |
| 14 | 17 | class ExternalReferenceRegistry { | |
| 15 | 18 | public: | |
| 16 | 19 | ExternalReferenceRegistry(); | |
| 17 | 20 | ||
| 18 | 21 | #define ALLOWED_EXTERNAL_REFERENCE_TYPES(V) \ | |
| 22 | + V(CFunctionCallback) \ | ||
| 23 | + V(const v8::CFunctionInfo*) \ | ||
| 19 | 24 | V(v8::FunctionCallback) \ | |
| 20 | 25 | V(v8::AccessorGetterCallback) \ | |
| 21 | 26 | V(v8::AccessorSetterCallback) \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,10 +3,16 @@ | |||
| 3 | 3 | ||
| 4 | 4 | #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | |
| 5 | 5 | ||
| 6 | + #include "node_snapshotable.h" | ||
| 7 | + #include "v8-fast-api-calls.h" | ||
| 6 | 8 | #include "v8.h" | |
| 7 | 9 | ||
| 8 | 10 | namespace node { | |
| 9 | 11 | ||
| 12 | + class Environment; | ||
| 13 | + class MemoryTracker; | ||
| 14 | + class ExternalReferenceRegistry; | ||
| 15 | + | ||
| 10 | 16 | v8::MaybeLocal<v8::Object> CreateEnvVarProxy(v8::Local<v8::Context> context, | |
| 11 | 17 | v8::Isolate* isolate); | |
| 12 | 18 | ||
@@ -38,6 +44,54 @@ v8::Maybe<bool> ProcessEmitDeprecationWarning(Environment* env, | |||
| 38 | 44 | v8::MaybeLocal<v8::Object> CreateProcessObject(Environment* env); | |
| 39 | 45 | void PatchProcessObject(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 40 | 46 | ||
| 47 | + namespace process { | ||
| 48 | + class BindingData : public SnapshotableObject { | ||
| 49 | + public: | ||
| 50 | + void AddMethods(); | ||
| 51 | + static void RegisterExternalReferences(ExternalReferenceRegistry* registry); | ||
| 52 | + | ||
| 53 | + SERIALIZABLE_OBJECT_METHODS() | ||
| 54 | + static constexpr FastStringKey type_name{"node::process::BindingData"}; | ||
| 55 | + static constexpr EmbedderObjectType type_int = | ||
| 56 | + EmbedderObjectType::k_process_binding_data; | ||
| 57 | + | ||
| 58 | + BindingData(Environment* env, v8::Local<v8::Object> object); | ||
| 59 | + | ||
| 60 | + void MemoryInfo(MemoryTracker* tracker) const override; | ||
| 61 | + SET_MEMORY_INFO_NAME(BindingData) | ||
| 62 | + SET_SELF_SIZE(BindingData) | ||
| 63 | + | ||
| 64 | + static BindingData* FromV8Value(v8::Local<v8::Value> receiver); | ||
| 65 | + static void NumberImpl(BindingData* receiver); | ||
| 66 | + | ||
| 67 | + static void FastNumber(v8::Local<v8::Value> receiver) { | ||
| 68 | + NumberImpl(FromV8Value(receiver)); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + static void SlowNumber(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 72 | + | ||
| 73 | + static void BigIntImpl(BindingData* receiver); | ||
| 74 | + | ||
| 75 | + static void FastBigInt(v8::Local<v8::Value> receiver) { | ||
| 76 | + BigIntImpl(FromV8Value(receiver)); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + static void SlowBigInt(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 80 | + | ||
| 81 | + private: | ||
| 82 | + static constexpr size_t kBufferSize = | ||
| 83 | + std::max(sizeof(uint64_t), sizeof(uint32_t) * 3); | ||
| 84 | + v8::Global<v8::ArrayBuffer> array_buffer_; | ||
| 85 | + std::shared_ptr<v8::BackingStore> backing_store_; | ||
| 86 | + | ||
| 87 | + // These need to be static so that we have their addresses available to | ||
| 88 | + // register as external references in the snapshot at environment creation | ||
| 89 | + // time. | ||
| 90 | + static v8::CFunction fast_number_; | ||
| 91 | + static v8::CFunction fast_bigint_; | ||
| 92 | + }; | ||
| 93 | + | ||
| 94 | + } // namespace process | ||
| 41 | 95 | } // namespace node | |
| 42 | 96 | #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | |
| 43 | 97 | #endif // SRC_NODE_PROCESS_H_ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments