Commit 81dc09fb authored by gsathya's avatar gsathya Committed by Commit bot

[csa] Refactor promises API

This removes all the promise allocation related methods from the CSA
and moves them PromiseBuiltinsAssembler with some edits.

BUG=v8:5343

Review-Url: https://codereview.chromium.org/2604273003
Cr-Commit-Position: refs/heads/master@{#42070}
parent ba668923
......@@ -17,8 +17,28 @@ typedef compiler::Node Node;
typedef CodeStubAssembler::ParameterMode ParameterMode;
typedef compiler::CodeAssemblerState CodeAssemblerState;
Node* PromiseBuiltinsAssembler::AllocateAndInitPromise(Node* context,
Node* parent) {
Node* PromiseBuiltinsAssembler::AllocateJSPromise(Node* context) {
Node* const native_context = LoadNativeContext(context);
Node* const promise_fun =
LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
Node* const initial_map =
LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
Node* const instance = AllocateJSObjectFromMap(initial_map);
return instance;
}
void PromiseBuiltinsAssembler::PromiseInit(Node* promise) {
StoreObjectField(promise, JSPromise::kStatusOffset,
SmiConstant(v8::Promise::kPending));
StoreObjectField(promise, JSPromise::kFlagsOffset, SmiConstant(0));
}
Node* PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Node* context) {
return AllocateAndInitJSPromise(context, UndefinedConstant());
}
Node* PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Node* context,
Node* parent) {
Node* const instance = AllocateJSPromise(context);
PromiseInit(instance);
......@@ -31,6 +51,28 @@ Node* PromiseBuiltinsAssembler::AllocateAndInitPromise(Node* context,
return instance;
}
Node* PromiseBuiltinsAssembler::AllocateAndSetJSPromise(Node* context,
Node* status,
Node* result) {
CSA_ASSERT(this, TaggedIsSmi(status));
Node* const instance = AllocateJSPromise(context);
StoreObjectFieldNoWriteBarrier(instance, JSPromise::kStatusOffset, status);
StoreObjectFieldNoWriteBarrier(instance, JSPromise::kResultOffset, result);
StoreObjectFieldNoWriteBarrier(instance, JSPromise::kFlagsOffset,
SmiConstant(0));
Label out(this);
GotoUnless(IsPromiseHookEnabled(), &out);
CallRuntime(Runtime::kPromiseHookInit, context, instance,
UndefinedConstant());
Goto(&out);
Bind(&out);
return instance;
}
std::pair<Node*, Node*>
PromiseBuiltinsAssembler::CreatePromiseResolvingFunctions(
Node* promise, Node* debug_event, Node* native_context) {
......@@ -337,7 +379,7 @@ Node* PromiseBuiltinsAssembler::InternalPromiseThen(Node* context,
Bind(&fast_promise_capability);
{
Node* const deferred_promise = AllocateAndInitPromise(context, promise);
Node* const deferred_promise = AllocateAndInitJSPromise(context, promise);
var_deferred_promise.Bind(deferred_promise);
var_deferred_on_resolve.Bind(UndefinedConstant());
var_deferred_on_reject.Bind(UndefinedConstant());
......@@ -791,7 +833,7 @@ TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
Node* const is_debug_active = IsDebugActive();
Label if_targetisnotmodified(this),
if_targetismodified(this, Label::kDeferred), run_executor(this),
debug_push(this), init(this);
debug_push(this);
Branch(WordEqual(promise_fun, new_target), &if_targetisnotmodified,
&if_targetismodified);
......@@ -802,9 +844,9 @@ TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
Bind(&if_targetisnotmodified);
{
Node* const instance = AllocateJSPromise(context);
Node* const instance = AllocateAndInitJSPromise(context);
var_result.Bind(instance);
Goto(&init);
Goto(&debug_push);
}
Bind(&if_targetismodified);
......@@ -812,16 +854,11 @@ TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
ConstructorBuiltinsAssembler constructor_assembler(this->state());
Node* const instance = constructor_assembler.EmitFastNewObject(
context, promise_fun, new_target);
PromiseInit(instance);
var_result.Bind(instance);
Goto(&init);
}
Bind(&init);
{
PromiseInit(var_result.value());
GotoUnless(IsPromiseHookEnabled(), &debug_push);
CallRuntime(Runtime::kPromiseHookInit, context, var_result.value(),
CallRuntime(Runtime::kPromiseHookInit, context, instance,
UndefinedConstant());
Goto(&debug_push);
}
......@@ -886,7 +923,7 @@ TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) {
Node* const parent = Parameter(1);
Node* const context = Parameter(4);
Return(AllocateAndInitPromise(context, parent));
Return(AllocateAndInitJSPromise(context, parent));
}
TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) {
......@@ -894,15 +931,7 @@ TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) {
Node* const result = Parameter(2);
Node* const context = Parameter(5);
Node* const instance = AllocateJSPromise(context);
PromiseSet(instance, status, result);
Label out(this);
GotoUnless(IsPromiseHookEnabled(), &out);
CallRuntime(Runtime::kPromiseHookInit, context, instance,
UndefinedConstant());
Goto(&out);
Bind(&out);
Node* const instance = AllocateAndSetJSPromise(context, status, result);
Return(instance);
}
......
......@@ -16,7 +16,19 @@ class PromiseBuiltinsAssembler : public CodeStubAssembler {
explicit PromiseBuiltinsAssembler(CodeAssemblerState* state)
: CodeStubAssembler(state) {}
Node* AllocateAndInitPromise(Node* context, Node* parent);
// These allocate and initialize a promise with pending state and
// undefined fields.
//
// This uses undefined as the parent promise for the promise init
// hook.
Node* AllocateAndInitJSPromise(Node* context);
// This uses the given parent as the parent promise for the promise
// init hook.
Node* AllocateAndInitJSPromise(Node* context, Node* parent);
// This allocates and initializes a promise with the given state and
// fields.
Node* AllocateAndSetJSPromise(Node* context, Node* status, Node* result);
Node* ThrowIfNotJSReceiver(Node* context, Node* value,
MessageTemplate::Template msg_template);
......@@ -57,6 +69,12 @@ class PromiseBuiltinsAssembler : public CodeStubAssembler {
Node* NewPromiseCapability(Node* context, Node* constructor,
Node* debug_event = nullptr);
protected:
void PromiseInit(Node* promise);
private:
Node* AllocateJSPromise(Node* context);
};
} // namespace internal
......
......@@ -8320,30 +8320,6 @@ Node* CodeStubAssembler::AllocateFunctionWithMapAndContext(Node* map,
return fun;
}
Node* CodeStubAssembler::AllocateJSPromise(Node* context) {
Node* const native_context = LoadNativeContext(context);
Node* const promise_fun =
LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
Node* const initial_map =
LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
Node* const instance = AllocateJSObjectFromMap(initial_map);
return instance;
}
void CodeStubAssembler::PromiseInit(Node* promise) {
StoreObjectField(promise, JSPromise::kStatusOffset,
SmiConstant(v8::Promise::kPending));
StoreObjectField(promise, JSPromise::kFlagsOffset, SmiConstant(0));
}
void CodeStubAssembler::PromiseSet(Node* promise, Node* status, Node* result) {
CSA_ASSERT(this, TaggedIsSmi(status));
StoreObjectField(promise, JSPromise::kStatusOffset, status);
StoreObjectField(promise, JSPromise::kResultOffset, result);
StoreObjectField(promise, JSPromise::kFlagsOffset, SmiConstant(0));
}
Node* CodeStubAssembler::AllocatePromiseReactionJobInfo(
Node* promise, Node* value, Node* tasks, Node* deferred_promise,
Node* deferred_on_resolve, Node* deferred_on_reject, Node* context) {
......
......@@ -1128,13 +1128,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
// Promise helpers
Node* IsPromiseHookEnabled();
Node* AllocateJSPromise(Node* context);
void PromiseInit(Node* promise);
// Other promise fields may also be need to set/reset. This only
// provides a helper for certain init patterns.
void PromiseSet(Node* promise, Node* status, Node* result);
Node* AllocatePromiseReactionJobInfo(Node* promise, Node* value, Node* tasks,
Node* deferred_promise,
Node* deferred_on_resolve,
......
......@@ -1789,37 +1789,15 @@ TEST(IsPromiseHookEnabled) {
CHECK_EQ(isolate->heap()->false_value(), *result);
}
TEST(AllocateJSPromise) {
TEST(AllocateAndInitJSPromise) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 1;
CodeAssemblerTester data(isolate, kNumParams);
CodeStubAssembler m(data.state());
Node* const context = m.Parameter(kNumParams + 2);
Node* const promise = m.AllocateJSPromise(context);
m.PromiseInit(promise);
m.Return(promise);
Handle<Code> code = data.GenerateCode();
CHECK(!code.is_null());
FunctionTester ft(code, kNumParams);
Handle<Object> result =
ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
CHECK(result->IsJSPromise());
}
TEST(PromiseInit) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 1;
CodeAssemblerTester data(isolate, kNumParams);
CodeStubAssembler m(data.state());
PromiseBuiltinsAssembler m(data.state());
Node* const context = m.Parameter(kNumParams + 2);
Node* const promise = m.AllocateJSPromise(context);
m.PromiseInit(promise);
Node* const promise = m.AllocateAndInitJSPromise(context);
m.Return(promise);
Handle<Code> code = data.GenerateCode();
......@@ -1829,22 +1807,18 @@ TEST(PromiseInit) {
Handle<Object> result =
ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
CHECK(result->IsJSPromise());
Handle<JSPromise> js_promise = Handle<JSPromise>::cast(result);
CHECK_EQ(v8::Promise::kPending, js_promise->status());
CHECK_EQ(isolate->heap()->undefined_value(), js_promise->result());
CHECK(!js_promise->has_handler());
}
TEST(PromiseSet) {
TEST(AllocateAndSetJSPromise) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 1;
CodeAssemblerTester data(isolate, kNumParams);
CodeStubAssembler m(data.state());
PromiseBuiltinsAssembler m(data.state());
Node* const context = m.Parameter(kNumParams + 2);
Node* const promise = m.AllocateJSPromise(context);
m.PromiseSet(promise, m.SmiConstant(v8::Promise::kPending), m.SmiConstant(1));
Node* const promise = m.AllocateAndSetJSPromise(
context, m.SmiConstant(v8::Promise::kPending), m.SmiConstant(1));
m.Return(promise);
Handle<Code> code = data.GenerateCode();
......@@ -1866,10 +1840,10 @@ TEST(AllocatePromiseReactionJobInfo) {
const int kNumParams = 1;
CodeAssemblerTester data(isolate, kNumParams);
CodeStubAssembler m(data.state());
PromiseBuiltinsAssembler p(data.state());
Node* const context = m.Parameter(kNumParams + 2);
Node* const promise = m.AllocateJSPromise(context);
m.PromiseInit(promise);
Node* const promise = p.AllocateAndInitJSPromise(context);
Node* const tasks = m.AllocateFixedArray(FAST_ELEMENTS, m.IntPtrConstant(1));
m.StoreFixedArrayElement(tasks, 0, m.UndefinedConstant());
Node* const deferred_promise =
......@@ -1955,8 +1929,8 @@ TEST(PromiseHasHandler) {
PromiseBuiltinsAssembler m(data.state());
Node* const context = m.Parameter(kNumParams + 2);
Node* const promise = m.AllocateJSPromise(context);
m.PromiseInit(promise);
Node* const promise =
m.AllocateAndInitJSPromise(context, m.UndefinedConstant());
m.Return(m.SelectBooleanConstant(m.PromiseHasHandler(promise)));
Handle<Code> code = data.GenerateCode();
......@@ -1977,8 +1951,8 @@ TEST(CreatePromiseResolvingFunctionsContext) {
Node* const context = m.Parameter(kNumParams + 2);
Node* const native_context = m.LoadNativeContext(context);
Node* const promise = m.AllocateJSPromise(context);
m.PromiseSet(promise, m.SmiConstant(v8::Promise::kPending), m.SmiConstant(1));
Node* const promise =
m.AllocateAndInitJSPromise(context, m.UndefinedConstant());
Node* const promise_context = m.CreatePromiseResolvingFunctionsContext(
promise, m.BooleanConstant(false), native_context);
m.Return(promise_context);
......@@ -2009,8 +1983,8 @@ TEST(CreatePromiseResolvingFunctions) {
Node* const context = m.Parameter(kNumParams + 2);
Node* const native_context = m.LoadNativeContext(context);
Node* const promise = m.AllocateJSPromise(context);
m.PromiseSet(promise, m.SmiConstant(v8::Promise::kPending), m.SmiConstant(1));
Node* const promise =
m.AllocateAndInitJSPromise(context, m.UndefinedConstant());
Node *resolve, *reject;
std::tie(resolve, reject) = m.CreatePromiseResolvingFunctions(
promise, m.BooleanConstant(false), native_context);
......@@ -2041,8 +2015,8 @@ TEST(AllocateFunctionWithMapAndContext) {
Node* const context = m.Parameter(kNumParams + 2);
Node* const native_context = m.LoadNativeContext(context);
Node* const promise = m.AllocateJSPromise(context);
m.PromiseSet(promise, m.SmiConstant(v8::Promise::kPending), m.SmiConstant(1));
Node* const promise =
m.AllocateAndInitJSPromise(context, m.UndefinedConstant());
Node* promise_context = m.CreatePromiseResolvingFunctionsContext(
promise, m.BooleanConstant(false), native_context);
Node* resolve_info =
......
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