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