Commit 6803eef1 authored by mattloring's avatar mattloring Committed by Commit bot

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}
parent d37dd4a6
...@@ -45,6 +45,9 @@ declare_args() { ...@@ -45,6 +45,9 @@ declare_args() {
# Sets -dENABLE_DISASSEMBLER. # Sets -dENABLE_DISASSEMBLER.
v8_enable_disassembler = "" v8_enable_disassembler = ""
# Sets the number of internal fields on promise objects.
v8_promise_internal_field_count = 0
# Sets -dENABLE_GDB_JIT_INTERFACE. # Sets -dENABLE_GDB_JIT_INTERFACE.
v8_enable_gdbjit = "" v8_enable_gdbjit = ""
...@@ -213,6 +216,10 @@ config("features") { ...@@ -213,6 +216,10 @@ config("features") {
if (v8_enable_disassembler) { if (v8_enable_disassembler) {
defines += [ "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) { if (v8_enable_future) {
defines += [ "V8_ENABLE_FUTURE" ] defines += [ "V8_ENABLE_FUTURE" ]
} }
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
'variables': { 'variables': {
'v8_enable_disassembler%': 0, 'v8_enable_disassembler%': 0,
'v8_promise_internal_field_count%': 0,
'v8_enable_gdbjit%': 0, 'v8_enable_gdbjit%': 0,
'v8_enable_verify_csa%': 0, 'v8_enable_verify_csa%': 0,
...@@ -77,6 +79,9 @@ ...@@ -77,6 +79,9 @@
['v8_enable_disassembler==1', { ['v8_enable_disassembler==1', {
'defines': ['ENABLE_DISASSEMBLER',], 'defines': ['ENABLE_DISASSEMBLER',],
}], }],
['v8_promise_internal_field_count!=0', {
'defines': ['V8_PROMISE_INTERNAL_FIELD_COUNT','v8_promise_internal_field_count'],
}],
['v8_enable_gdbjit==1', { ['v8_enable_gdbjit==1', {
'defines': ['ENABLE_GDB_JIT_INTERFACE',], 'defines': ['ENABLE_GDB_JIT_INTERFACE',],
}], }],
......
...@@ -3861,6 +3861,10 @@ class V8_EXPORT Function : public Object { ...@@ -3861,6 +3861,10 @@ class V8_EXPORT Function : public Object {
static void CheckCast(Value* obj); 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). * An instance of the built-in Promise constructor (ES6 draft).
...@@ -3942,6 +3946,8 @@ class V8_EXPORT Promise : public Object { ...@@ -3942,6 +3946,8 @@ class V8_EXPORT Promise : public Object {
V8_INLINE static Promise* Cast(Value* obj); V8_INLINE static Promise* Cast(Value* obj);
static const int kEmbedderFieldCount = V8_PROMISE_INTERNAL_FIELD_COUNT;
private: private:
Promise(); Promise();
static void CheckCast(Value* obj); static void CheckCast(Value* obj);
......
...@@ -2105,8 +2105,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, ...@@ -2105,8 +2105,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
{ // -- P r o m i s e { // -- P r o m i s e
Handle<JSObject> prototype = Handle<JSObject> prototype =
factory->NewJSObject(isolate->object_function(), TENURED); factory->NewJSObject(isolate->object_function(), TENURED);
Handle<JSFunction> promise_fun = Handle<JSFunction> promise_fun = InstallFunction(
InstallFunction(global, "Promise", JS_PROMISE_TYPE, JSPromise::kSize, global, "Promise", JS_PROMISE_TYPE, JSPromise::kSizeWithEmbedderFields,
prototype, Builtins::kPromiseConstructor); prototype, Builtins::kPromiseConstructor);
InstallWithIntrinsicDefaultProto(isolate, promise_fun, InstallWithIntrinsicDefaultProto(isolate, promise_fun,
Context::PROMISE_FUNCTION_INDEX); Context::PROMISE_FUNCTION_INDEX);
......
...@@ -31,6 +31,10 @@ void PromiseBuiltinsAssembler::PromiseInit(Node* promise) { ...@@ -31,6 +31,10 @@ void PromiseBuiltinsAssembler::PromiseInit(Node* promise) {
SmiConstant(v8::Promise::kPending)); SmiConstant(v8::Promise::kPending));
StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset, StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset,
SmiConstant(0)); 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) { Node* PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Node* context) {
...@@ -62,6 +66,10 @@ Node* PromiseBuiltinsAssembler::AllocateAndSetJSPromise(Node* context, ...@@ -62,6 +66,10 @@ Node* PromiseBuiltinsAssembler::AllocateAndSetJSPromise(Node* context,
StoreObjectFieldNoWriteBarrier(instance, JSPromise::kResultOffset, result); StoreObjectFieldNoWriteBarrier(instance, JSPromise::kResultOffset, result);
StoreObjectFieldNoWriteBarrier(instance, JSPromise::kFlagsOffset, StoreObjectFieldNoWriteBarrier(instance, JSPromise::kFlagsOffset,
SmiConstant(0)); 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); Label out(this);
GotoIfNot(IsPromiseHookEnabledOrDebugIsActive(), &out); GotoIfNot(IsPromiseHookEnabledOrDebugIsActive(), &out);
......
...@@ -928,6 +928,9 @@ Handle<JSPromise> Factory::NewJSPromise() { ...@@ -928,6 +928,9 @@ Handle<JSPromise> Factory::NewJSPromise() {
Handle<JSPromise> promise = Handle<JSPromise>::cast(promise_obj); Handle<JSPromise> promise = Handle<JSPromise>::cast(promise_obj);
promise->set_status(v8::Promise::kPending); promise->set_status(v8::Promise::kPending);
promise->set_flags(0); 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()); isolate()->RunPromiseHook(PromiseHookType::kInit, promise, undefined_value());
return promise; return promise;
......
...@@ -6565,6 +6565,8 @@ class JSPromise : public JSObject { ...@@ -6565,6 +6565,8 @@ class JSPromise : public JSObject {
kFulfillReactionsOffset + kPointerSize; kFulfillReactionsOffset + kPointerSize;
static const int kFlagsOffset = kRejectReactionsOffset + kPointerSize; static const int kFlagsOffset = kRejectReactionsOffset + kPointerSize;
static const int kSize = kFlagsOffset + kPointerSize; static const int kSize = kFlagsOffset + kPointerSize;
static const int kSizeWithEmbedderFields =
kSize + v8::Promise::kEmbedderFieldCount * kPointerSize;
// Flags layout. // Flags layout.
static const int kHasHandlerBit = 0; static const int kHasHandlerBit = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment