Allow embedder to set promise internal field count
Asynchronous context tracking mechanisms in Node.js need to store some state on all promise objects. This change will allow embedders to configure the number of internal fields on promises as is already done for ArrayBuffers. BUG=v8:6435 Review-Url: https://codereview.chromium.org/2889863002 Cr-Commit-Position: refs/heads/master@{#45496}
This commit is contained in:
parent
d37dd4a66e
commit
6803eef142
7
BUILD.gn
7
BUILD.gn
@ -45,6 +45,9 @@ declare_args() {
|
||||
# Sets -dENABLE_DISASSEMBLER.
|
||||
v8_enable_disassembler = ""
|
||||
|
||||
# Sets the number of internal fields on promise objects.
|
||||
v8_promise_internal_field_count = 0
|
||||
|
||||
# Sets -dENABLE_GDB_JIT_INTERFACE.
|
||||
v8_enable_gdbjit = ""
|
||||
|
||||
@ -213,6 +216,10 @@ config("features") {
|
||||
if (v8_enable_disassembler) {
|
||||
defines += [ "ENABLE_DISASSEMBLER" ]
|
||||
}
|
||||
if (v8_promise_internal_field_count != 0) {
|
||||
defines +=
|
||||
[ "V8_PROMISE_INTERNAL_FIELD_COUNT=${v8_promise_internal_field_count}" ]
|
||||
}
|
||||
if (v8_enable_future) {
|
||||
defines += [ "V8_ENABLE_FUTURE" ]
|
||||
}
|
||||
|
@ -31,6 +31,8 @@
|
||||
'variables': {
|
||||
'v8_enable_disassembler%': 0,
|
||||
|
||||
'v8_promise_internal_field_count%': 0,
|
||||
|
||||
'v8_enable_gdbjit%': 0,
|
||||
|
||||
'v8_enable_verify_csa%': 0,
|
||||
@ -77,6 +79,9 @@
|
||||
['v8_enable_disassembler==1', {
|
||||
'defines': ['ENABLE_DISASSEMBLER',],
|
||||
}],
|
||||
['v8_promise_internal_field_count!=0', {
|
||||
'defines': ['V8_PROMISE_INTERNAL_FIELD_COUNT','v8_promise_internal_field_count'],
|
||||
}],
|
||||
['v8_enable_gdbjit==1', {
|
||||
'defines': ['ENABLE_GDB_JIT_INTERFACE',],
|
||||
}],
|
||||
|
@ -3861,6 +3861,10 @@ class V8_EXPORT Function : public Object {
|
||||
static void CheckCast(Value* obj);
|
||||
};
|
||||
|
||||
#ifndef V8_PROMISE_INTERNAL_FIELD_COUNT
|
||||
// The number of required internal fields can be defined by embedder.
|
||||
#define V8_PROMISE_INTERNAL_FIELD_COUNT 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* An instance of the built-in Promise constructor (ES6 draft).
|
||||
@ -3942,6 +3946,8 @@ class V8_EXPORT Promise : public Object {
|
||||
|
||||
V8_INLINE static Promise* Cast(Value* obj);
|
||||
|
||||
static const int kEmbedderFieldCount = V8_PROMISE_INTERNAL_FIELD_COUNT;
|
||||
|
||||
private:
|
||||
Promise();
|
||||
static void CheckCast(Value* obj);
|
||||
|
@ -2105,9 +2105,9 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
{ // -- P r o m i s e
|
||||
Handle<JSObject> prototype =
|
||||
factory->NewJSObject(isolate->object_function(), TENURED);
|
||||
Handle<JSFunction> promise_fun =
|
||||
InstallFunction(global, "Promise", JS_PROMISE_TYPE, JSPromise::kSize,
|
||||
prototype, Builtins::kPromiseConstructor);
|
||||
Handle<JSFunction> promise_fun = InstallFunction(
|
||||
global, "Promise", JS_PROMISE_TYPE, JSPromise::kSizeWithEmbedderFields,
|
||||
prototype, Builtins::kPromiseConstructor);
|
||||
InstallWithIntrinsicDefaultProto(isolate, promise_fun,
|
||||
Context::PROMISE_FUNCTION_INDEX);
|
||||
|
||||
|
@ -31,6 +31,10 @@ void PromiseBuiltinsAssembler::PromiseInit(Node* promise) {
|
||||
SmiConstant(v8::Promise::kPending));
|
||||
StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset,
|
||||
SmiConstant(0));
|
||||
for (int i = 0; i < v8::Promise::kEmbedderFieldCount; i++) {
|
||||
int offset = JSPromise::kSize + i * kPointerSize;
|
||||
StoreObjectFieldNoWriteBarrier(promise, offset, SmiConstant(Smi::kZero));
|
||||
}
|
||||
}
|
||||
|
||||
Node* PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Node* context) {
|
||||
@ -62,6 +66,10 @@ Node* PromiseBuiltinsAssembler::AllocateAndSetJSPromise(Node* context,
|
||||
StoreObjectFieldNoWriteBarrier(instance, JSPromise::kResultOffset, result);
|
||||
StoreObjectFieldNoWriteBarrier(instance, JSPromise::kFlagsOffset,
|
||||
SmiConstant(0));
|
||||
for (int i = 0; i < v8::Promise::kEmbedderFieldCount; i++) {
|
||||
int offset = JSPromise::kSize + i * kPointerSize;
|
||||
StoreObjectFieldNoWriteBarrier(instance, offset, SmiConstant(Smi::kZero));
|
||||
}
|
||||
|
||||
Label out(this);
|
||||
GotoIfNot(IsPromiseHookEnabledOrDebugIsActive(), &out);
|
||||
|
@ -928,6 +928,9 @@ Handle<JSPromise> Factory::NewJSPromise() {
|
||||
Handle<JSPromise> promise = Handle<JSPromise>::cast(promise_obj);
|
||||
promise->set_status(v8::Promise::kPending);
|
||||
promise->set_flags(0);
|
||||
for (int i = 0; i < v8::Promise::kEmbedderFieldCount; i++) {
|
||||
promise->SetEmbedderField(i, Smi::kZero);
|
||||
}
|
||||
|
||||
isolate()->RunPromiseHook(PromiseHookType::kInit, promise, undefined_value());
|
||||
return promise;
|
||||
|
@ -6565,6 +6565,8 @@ class JSPromise : public JSObject {
|
||||
kFulfillReactionsOffset + kPointerSize;
|
||||
static const int kFlagsOffset = kRejectReactionsOffset + kPointerSize;
|
||||
static const int kSize = kFlagsOffset + kPointerSize;
|
||||
static const int kSizeWithEmbedderFields =
|
||||
kSize + v8::Promise::kEmbedderFieldCount * kPointerSize;
|
||||
|
||||
// Flags layout.
|
||||
static const int kHasHandlerBit = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user