Commit 34b7b21d authored by bmeurer's avatar bmeurer Committed by Commit bot

[builtins] One runtime fallback is enough for the String constructor.

If inline allocation fails, we can just use the %NewObject fallback,
which will do the right thing. We don't need a dedicated fallback to
%AllocateInNewSpace.

R=verwaest@chromium.org

Review URL: https://codereview.chromium.org/1440193003

Cr-Commit-Position: refs/heads/master@{#32000}
parent 20589911
...@@ -251,7 +251,12 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -251,7 +251,12 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ bind(&done_convert); __ bind(&done_convert);
} }
// 3. Allocate a JSValue wrapper for the string. // 3. Check if original constructor and constructor differ.
Label new_object;
__ cmp(r1, r3);
__ b(ne, &new_object);
// 4. Allocate a JSValue wrapper for the string.
{ {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- r2 : the first argument // -- r2 : the first argument
...@@ -259,15 +264,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -259,15 +264,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
// -- r3 : original constructor // -- r3 : original constructor
// -- lr : return address // -- lr : return address
// ----------------------------------- // -----------------------------------
__ Allocate(JSValue::kSize, r0, r4, r5, &new_object, TAG_OBJECT);
Label allocate, done_allocate, rt_call;
// Fall back to runtime if the original constructor and function differ.
__ cmp(r1, r3);
__ b(ne, &rt_call);
__ Allocate(JSValue::kSize, r0, r3, r4, &allocate, TAG_OBJECT);
__ bind(&done_allocate);
// Initialize the JSValue in r0. // Initialize the JSValue in r0.
__ LoadGlobalFunctionInitialMap(r1, r3, r4); __ LoadGlobalFunctionInitialMap(r1, r3, r4);
...@@ -278,30 +275,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -278,30 +275,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset));
STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
__ Ret(); __ Ret();
}
// Fallback to the runtime to allocate in new space. // 5. Fallback to the runtime to create new object.
__ bind(&allocate); __ bind(&new_object);
{ {
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Move(r3, Smi::FromInt(JSValue::kSize)); __ Push(r2, r1, r3); // first argument, constructor, original constructor
__ Push(r1, r2, r3); __ CallRuntime(Runtime::kNewObject, 2);
__ CallRuntime(Runtime::kAllocateInNewSpace, 1); __ Pop(r2);
__ Pop(r1, r2);
}
__ b(&done_allocate);
// Fallback to the runtime to create new object.
__ bind(&rt_call);
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ Push(r1, r2);
__ Push(r1, r3); // constructor function, original constructor
__ CallRuntime(Runtime::kNewObject, 2);
__ Pop(r1, r2);
}
__ str(r2, FieldMemOperand(r0, JSValue::kValueOffset));
__ Ret();
} }
__ str(r2, FieldMemOperand(r0, JSValue::kValueOffset));
__ Ret();
} }
......
...@@ -247,7 +247,12 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -247,7 +247,12 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ Bind(&done_convert); __ Bind(&done_convert);
} }
// 3. Allocate a JSValue wrapper for the string. // 3. Check if original constructor and constructor differ.
Label new_object;
__ Cmp(x1, x3);
__ B(ne, &new_object);
// 4. Allocate a JSValue wrapper for the string.
{ {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- x2 : the first argument // -- x2 : the first argument
...@@ -255,15 +260,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -255,15 +260,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
// -- x3 : original constructor // -- x3 : original constructor
// -- lr : return address // -- lr : return address
// ----------------------------------- // -----------------------------------
__ Allocate(JSValue::kSize, x0, x4, x5, &new_object, TAG_OBJECT);
Label allocate, done_allocate, rt_call;
// Fall back to runtime if the original constructor and function differ.
__ cmp(x1, x3);
__ B(ne, &rt_call);
__ Allocate(JSValue::kSize, x0, x3, x4, &allocate, TAG_OBJECT);
__ Bind(&done_allocate);
// Initialize the JSValue in eax. // Initialize the JSValue in eax.
__ LoadGlobalFunctionInitialMap(x1, x3, x4); __ LoadGlobalFunctionInitialMap(x1, x3, x4);
...@@ -274,29 +271,19 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -274,29 +271,19 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset)); __ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset));
STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
__ Ret(); __ Ret();
}
// Fallback to the runtime to allocate in new space. // 5. Fallback to the runtime to create new object.
__ Bind(&allocate); __ bind(&new_object);
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameScope scope(masm, StackFrame::INTERNAL);
__ Push(x1, x2); __ Push(x2, x1); // first argument, constructor
__ Push(Smi::FromInt(JSValue::kSize)); __ Push(x1, x3); // constructor, original constructor
__ CallRuntime(Runtime::kAllocateInNewSpace, 1); __ CallRuntime(Runtime::kNewObject, 2);
__ Pop(x2, x1); __ Pop(x1, x2);
}
__ B(&done_allocate);
// Fallback to the runtime to create new object.
__ bind(&rt_call);
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ Push(x1, x2, x1, x3); // constructor function, original constructor
__ CallRuntime(Runtime::kNewObject, 2);
__ Pop(x2, x1);
}
__ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset));
__ Ret();
} }
__ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset));
__ Ret();
} }
......
...@@ -1407,22 +1407,19 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -1407,22 +1407,19 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ bind(&done_convert); __ bind(&done_convert);
} }
// 3. Allocate a JSValue wrapper for the string. // 3. Check if original constructor and constructor differ.
Label new_object;
__ cmp(edx, edi);
__ j(not_equal, &new_object);
// 4. Allocate a JSValue wrapper for the string.
{ {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- ebx : the first argument // -- ebx : the first argument
// -- edi : constructor function // -- edi : constructor function
// -- edx : original constructor // -- edx : original constructor
// ----------------------------------- // -----------------------------------
__ Allocate(JSValue::kSize, eax, ecx, no_reg, &new_object, TAG_OBJECT);
Label allocate, done_allocate, rt_call;
// Fall back to runtime if the original constructor and constructor differ.
__ cmp(edx, edi);
__ j(not_equal, &rt_call);
__ Allocate(JSValue::kSize, eax, ecx, no_reg, &allocate, TAG_OBJECT);
__ bind(&done_allocate);
// Initialize the JSValue in eax. // Initialize the JSValue in eax.
__ LoadGlobalFunctionInitialMap(edi, ecx); __ LoadGlobalFunctionInitialMap(edi, ecx);
...@@ -1434,35 +1431,19 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -1434,35 +1431,19 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ mov(FieldOperand(eax, JSValue::kValueOffset), ebx); __ mov(FieldOperand(eax, JSValue::kValueOffset), ebx);
STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
__ Ret(); __ Ret();
}
// Fallback to the runtime to allocate in new space. // 5. Fallback to the runtime to create new object.
__ bind(&allocate); __ bind(&new_object);
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameScope scope(masm, StackFrame::INTERNAL);
__ Push(ebx); __ Push(ebx); // the first argument
__ Push(edi); __ Push(edi); // constructor function
__ Push(Smi::FromInt(JSValue::kSize)); __ Push(edx); // original constructor
__ CallRuntime(Runtime::kAllocateInNewSpace, 1); __ CallRuntime(Runtime::kNewObject, 2);
__ Pop(edi); __ Pop(FieldOperand(eax, JSValue::kValueOffset));
__ Pop(ebx);
}
__ jmp(&done_allocate);
// Fallback to the runtime to create new object.
__ bind(&rt_call);
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ Push(ebx);
__ Push(edi);
__ Push(edi); // constructor function
__ Push(edx); // original constructor
__ CallRuntime(Runtime::kNewObject, 2);
__ Pop(edi);
__ Pop(ebx);
}
__ mov(FieldOperand(eax, JSValue::kValueOffset), ebx);
__ Ret();
} }
__ Ret();
} }
......
...@@ -841,6 +841,7 @@ class MacroAssembler: public Assembler { ...@@ -841,6 +841,7 @@ class MacroAssembler: public Assembler {
void Push(const Operand& src) { push(src); } void Push(const Operand& src) { push(src); }
void Push(Immediate value) { push(value); } void Push(Immediate value) { push(value); }
void Pop(Register dst) { pop(dst); } void Pop(Register dst) { pop(dst); }
void Pop(const Operand& dst) { pop(dst); }
void PushReturnAddressFrom(Register src) { push(src); } void PushReturnAddressFrom(Register src) { push(src); }
void PopReturnAddressTo(Register dst) { pop(dst); } void PopReturnAddressTo(Register dst) { pop(dst); }
......
...@@ -267,7 +267,11 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -267,7 +267,11 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ bind(&done_convert); __ bind(&done_convert);
} }
// 3. Allocate a JSValue wrapper for the string. // 3. Check if original constructor and constructor differ.
Label new_object;
__ Branch(&new_object, ne, a1, Operand(a3));
// 4. Allocate a JSValue wrapper for the string.
{ {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- a0 : the first argument // -- a0 : the first argument
...@@ -275,14 +279,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -275,14 +279,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
// -- a3 : original constructor // -- a3 : original constructor
// -- ra : return address // -- ra : return address
// ----------------------------------- // -----------------------------------
__ Allocate(JSValue::kSize, v0, a2, t0, &new_object, TAG_OBJECT);
Label allocate, done_allocate, rt_call;
// Fall back to runtime if the original constructor and function differ.
__ Branch(&rt_call, ne, a1, Operand(a3));
__ Allocate(JSValue::kSize, v0, a2, a3, &allocate, TAG_OBJECT);
__ bind(&done_allocate);
// Initialize the JSValue in eax. // Initialize the JSValue in eax.
__ LoadGlobalFunctionInitialMap(a1, a2, a3); __ LoadGlobalFunctionInitialMap(a1, a2, a3);
...@@ -293,29 +290,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -293,29 +290,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ Ret(USE_DELAY_SLOT); __ Ret(USE_DELAY_SLOT);
__ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset)); __ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset));
STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
}
// Fallback to the runtime to allocate in new space. // 5. Fallback to the runtime to create new object.
__ bind(&allocate); __ bind(&new_object);
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameScope scope(masm, StackFrame::INTERNAL);
__ Move(a2, Smi::FromInt(JSValue::kSize)); __ Push(a0, a1, a3); // first argument, constructor, original constructor
__ Push(a0, a1, a2); __ CallRuntime(Runtime::kNewObject, 2);
__ CallRuntime(Runtime::kAllocateInNewSpace, 1); __ Pop(a0);
__ Pop(a0, a1);
}
__ jmp(&done_allocate);
// Fallback to the runtime to create new object.
__ bind(&rt_call);
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ Push(a0, a1, a1, a3); // constructor function, original constructor
__ CallRuntime(Runtime::kNewObject, 2);
__ Pop(a0, a1);
}
__ Ret(USE_DELAY_SLOT);
__ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset));
} }
__ Ret(USE_DELAY_SLOT);
__ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset));
} }
......
...@@ -264,7 +264,11 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -264,7 +264,11 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ bind(&done_convert); __ bind(&done_convert);
} }
// 3. Allocate a JSValue wrapper for the string. // 3. Check if original constructor and constructor differ.
Label new_object;
__ Branch(&new_object, ne, a1, Operand(a3));
// 4. Allocate a JSValue wrapper for the string.
{ {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- a0 : the first argument // -- a0 : the first argument
...@@ -272,14 +276,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -272,14 +276,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
// -- a3 : original constructor // -- a3 : original constructor
// -- ra : return address // -- ra : return address
// ----------------------------------- // -----------------------------------
__ Allocate(JSValue::kSize, v0, a2, t0, &new_object, TAG_OBJECT);
Label allocate, done_allocate, rt_call;
// Fall back to runtime if the original constructor and function differ.
__ Branch(&rt_call, ne, a1, Operand(a3));
__ Allocate(JSValue::kSize, v0, a2, a3, &allocate, TAG_OBJECT);
__ bind(&done_allocate);
// Initialize the JSValue in eax. // Initialize the JSValue in eax.
__ LoadGlobalFunctionInitialMap(a1, a2, a3); __ LoadGlobalFunctionInitialMap(a1, a2, a3);
...@@ -290,29 +287,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -290,29 +287,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset)); __ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset));
STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
__ Ret(); __ Ret();
}
// Fallback to the runtime to allocate in new space. // 5. Fallback to the runtime to create new object.
__ bind(&allocate); __ bind(&new_object);
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameScope scope(masm, StackFrame::INTERNAL);
__ Move(a2, Smi::FromInt(JSValue::kSize)); __ Push(a0, a1, a3); // first argument, constructor, original constructor
__ Push(a0, a1, a2); __ CallRuntime(Runtime::kNewObject, 2);
__ CallRuntime(Runtime::kAllocateInNewSpace, 1); __ Pop(a0);
__ Pop(a0, a1);
}
__ jmp(&done_allocate);
// Fallback to the runtime to create new object.
__ bind(&rt_call);
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ Push(a0, a1, a1, a3); // constructor function, original constructor
__ CallRuntime(Runtime::kNewObject, 2);
__ Pop(a0, a1);
}
__ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset));
__ Ret();
} }
__ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset));
__ Ret();
} }
......
...@@ -1468,21 +1468,19 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -1468,21 +1468,19 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ bind(&done_convert); __ bind(&done_convert);
} }
// 3. Allocate a JSValue wrapper for the string. // 3. Check if original constructor and constructor differ.
Label new_object;
__ cmpp(rdx, rdi);
__ j(not_equal, &new_object);
// 4. Allocate a JSValue wrapper for the string.
{ {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- rbx : the first argument // -- rbx : the first argument
// -- rdi : constructor function // -- rdi : constructor function
// -- rdx : original constructor // -- rdx : original constructor
// ----------------------------------- // -----------------------------------
Label allocate, done_allocate, rt_call; __ Allocate(JSValue::kSize, rax, rcx, no_reg, &new_object, TAG_OBJECT);
// Fall back to runtime if the original constructor and constructor differ.
__ cmpp(rdx, rdi);
__ j(not_equal, &rt_call);
__ Allocate(JSValue::kSize, rax, rcx, no_reg, &allocate, TAG_OBJECT);
__ bind(&done_allocate);
// Initialize the JSValue in rax. // Initialize the JSValue in rax.
__ LoadGlobalFunctionInitialMap(rdi, rcx); __ LoadGlobalFunctionInitialMap(rdi, rcx);
...@@ -1493,35 +1491,19 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { ...@@ -1493,35 +1491,19 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ movp(FieldOperand(rax, JSValue::kValueOffset), rbx); __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx);
STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
__ Ret(); __ Ret();
}
// Fallback to the runtime to allocate in new space. // 5. Fallback to the runtime to create new object.
__ bind(&allocate); __ bind(&new_object);
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameScope scope(masm, StackFrame::INTERNAL);
__ Push(rbx); __ Push(rbx); // the first argument
__ Push(rdi); __ Push(rdi); // constructor function
__ Push(Smi::FromInt(JSValue::kSize)); __ Push(rdx); // original constructor
__ CallRuntime(Runtime::kAllocateInNewSpace, 1); __ CallRuntime(Runtime::kNewObject, 2);
__ Pop(rdi); __ Pop(FieldOperand(rax, JSValue::kValueOffset));
__ Pop(rbx);
}
__ jmp(&done_allocate);
// Fallback to the runtime to create new object.
__ bind(&rt_call);
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ Push(rbx);
__ Push(rdi);
__ Push(rdi); // constructor function
__ Push(rdx); // original constructor
__ CallRuntime(Runtime::kNewObject, 2);
__ Pop(rdi);
__ Pop(rbx);
}
__ movp(FieldOperand(rax, JSValue::kValueOffset), rbx);
__ Ret();
} }
__ Ret();
} }
......
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