Commit 0ac77409 authored by bjaideep's avatar bjaideep Committed by Commit bot

PPC/s390: [builtins] Construct builtin frame in String/Number ctors

Port d49d3864

R=jgruber@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com, mbrandy@us.ibm.com

BUG=v8:5173
LOG=N

Review-Url: https://codereview.chromium.org/2141723003
Cr-Commit-Position: refs/heads/master@{#37659}
parent 1d26ed29
......@@ -172,14 +172,17 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
{
// Parameter is not a Number, use the ToNumber builtin to convert it.
FrameScope scope(masm, StackFrame::MANUAL);
__ PushStandardFrame(r4);
__ SmiTag(r3);
__ SmiTag(r7);
__ Push(r3, r7, r8);
__ EnterBuiltinFrame(cp, r4, r3);
__ Push(r7, r8);
__ mr(r3, r5);
__ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ mr(r5, r3);
__ Pop(r3, r7, r8);
__ Pop(r7, r8);
__ LeaveBuiltinFrame(cp, r4, r3);
__ SmiUntag(r7);
__ SmiUntag(r3);
{
// Restore the double accumulator value (d1).
Label done_restore;
......@@ -188,15 +191,6 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
__ lfd(d1, FieldMemOperand(r8, HeapNumber::kValueOffset));
__ bind(&done_restore);
}
__ SmiUntag(r7);
__ SmiUntag(r3);
// TODO(Jaideep): Add macro furtion for PopStandardFrame
if (FLAG_enable_embedded_constant_pool) {
__ Pop(r0, fp, kConstantPoolRegister, cp, r4);
} else {
__ Pop(r0, fp, cp, r4);
}
__ mtlr(r0);
}
__ b(&convert);
__ bind(&convert_number);
......@@ -245,25 +239,38 @@ void Builtins::Generate_NumberConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : number of arguments
// -- r4 : constructor function
// -- cp : context
// -- lr : return address
// -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
// -- sp[argc * 4] : receiver
// -----------------------------------
// 1. Load the first argument into r3 and get rid of the rest (including the
// receiver).
// 1. Load the first argument into r3.
Label no_arguments;
{
__ mr(r5, r3); // Store argc in r5.
__ cmpi(r3, Operand::Zero());
__ beq(&no_arguments);
__ subi(r3, r3, Operand(1));
__ ShiftLeftImm(r3, r3, Operand(kPointerSizeLog2));
__ LoadPUX(r3, MemOperand(sp, r3));
__ Drop(2);
__ LoadPX(r3, MemOperand(sp, r3));
}
// 2a. Convert the first argument to a number.
__ Jump(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
{
FrameScope scope(masm, StackFrame::MANUAL);
__ SmiTag(r5);
__ EnterBuiltinFrame(cp, r4, r5);
__ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ LeaveBuiltinFrame(cp, r4, r5);
__ SmiUntag(r5);
}
{
// Drop all arguments including the receiver.
__ Drop(r5);
__ Ret(1);
}
// 2b. No arguments, return +0.
__ bind(&no_arguments);
......@@ -278,6 +285,7 @@ void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
// -- r3 : number of arguments
// -- r4 : constructor function
// -- r6 : new target
// -- cp : context
// -- lr : return address
// -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
// -- sp[argc * 4] : receiver
......@@ -286,20 +294,18 @@ void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
// 1. Make sure we operate in the context of the called function.
__ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
// 2. Load the first argument into r5 and get rid of the rest (including the
// receiver).
// 2. Load the first argument into r5.
{
Label no_arguments, done;
__ mr(r9, r3); // Store argc in r9.
__ cmpi(r3, Operand::Zero());
__ beq(&no_arguments);
__ subi(r3, r3, Operand(1));
__ ShiftLeftImm(r5, r3, Operand(kPointerSizeLog2));
__ LoadPUX(r5, MemOperand(sp, r5));
__ Drop(2);
__ LoadPX(r5, MemOperand(sp, r5));
__ b(&done);
__ bind(&no_arguments);
__ LoadSmiLiteral(r5, Smi::FromInt(0));
__ Drop(1);
__ bind(&done);
}
......@@ -310,36 +316,49 @@ void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
__ CompareObjectType(r5, r7, r7, HEAP_NUMBER_TYPE);
__ beq(&done_convert);
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Push(r4, r6);
FrameScope scope(masm, StackFrame::MANUAL);
__ SmiTag(r9);
__ EnterBuiltinFrame(cp, r4, r9);
__ Push(r6);
__ mr(r3, r5);
__ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ mr(r5, r3);
__ Pop(r4, r6);
__ Pop(r6);
__ LeaveBuiltinFrame(cp, r4, r9);
__ SmiUntag(r9);
}
__ bind(&done_convert);
}
// 4. Check if new target and constructor differ.
Label new_object;
Label drop_frame_and_ret, new_object;
__ cmp(r4, r6);
__ bne(&new_object);
// 5. Allocate a JSValue wrapper for the number.
__ AllocateJSValue(r3, r4, r5, r7, r8, &new_object);
__ Ret();
__ b(&drop_frame_and_ret);
// 6. Fallback to the runtime to create new object.
__ bind(&new_object);
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
FrameScope scope(masm, StackFrame::MANUAL);
__ SmiTag(r9);
__ EnterBuiltinFrame(cp, r4, r9);
__ Push(r5); // first argument
FastNewObjectStub stub(masm->isolate());
__ CallStub(&stub);
__ Pop(r5);
__ LeaveBuiltinFrame(cp, r4, r9);
__ SmiUntag(r9);
}
__ StoreP(r5, FieldMemOperand(r3, JSValue::kValueOffset), r0);
__ Ret();
__ bind(&drop_frame_and_ret);
{
__ Drop(r9);
__ Ret(1);
}
}
......@@ -348,33 +367,33 @@ void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : number of arguments
// -- r4 : constructor function
// -- cp : context
// -- lr : return address
// -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
// -- sp[argc * 4] : receiver
// -----------------------------------
// 1. Load the first argument into r3 and get rid of the rest (including the
// receiver).
// 1. Load the first argument into r3.
Label no_arguments;
{
__ mr(r5, r3); // Store argc in r5.
__ cmpi(r3, Operand::Zero());
__ beq(&no_arguments);
__ subi(r3, r3, Operand(1));
__ ShiftLeftImm(r3, r3, Operand(kPointerSizeLog2));
__ LoadPUX(r3, MemOperand(sp, r3));
__ Drop(2);
__ LoadPX(r3, MemOperand(sp, r3));
}
// 2a. At least one argument, return r3 if it's a string, otherwise
// dispatch to appropriate conversion.
Label to_string, symbol_descriptive_string;
Label drop_frame_and_ret, to_string, symbol_descriptive_string;
{
__ JumpIfSmi(r3, &to_string);
STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE);
__ CompareObjectType(r3, r4, r4, FIRST_NONSTRING_TYPE);
__ CompareObjectType(r3, r6, r6, FIRST_NONSTRING_TYPE);
__ bgt(&to_string);
__ beq(&symbol_descriptive_string);
__ Ret();
__ b(&drop_frame_and_ret);
}
// 2b. No arguments, return the empty string (and pop the receiver).
......@@ -387,18 +406,31 @@ void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
// 3a. Convert r3 to a string.
__ bind(&to_string);
{
FrameScope scope(masm, StackFrame::MANUAL);
ToStringStub stub(masm->isolate());
__ TailCallStub(&stub);
__ SmiTag(r5);
__ EnterBuiltinFrame(cp, r4, r5);
__ CallStub(&stub);
__ LeaveBuiltinFrame(cp, r4, r5);
__ SmiUntag(r5);
}
__ b(&drop_frame_and_ret);
// 3b. Convert symbol in r3 to a string.
__ bind(&symbol_descriptive_string);
{
__ Drop(r5);
__ Drop(1);
__ Push(r3);
__ TailCallRuntime(Runtime::kSymbolDescriptiveString);
}
}
__ bind(&drop_frame_and_ret);
{
__ Drop(r5);
__ Ret(1);
}
}
// static
void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
......@@ -406,6 +438,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
// -- r3 : number of arguments
// -- r4 : constructor function
// -- r6 : new target
// -- cp : context
// -- lr : return address
// -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
// -- sp[argc * 4] : receiver
......@@ -414,20 +447,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
// 1. Make sure we operate in the context of the called function.
__ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
// 2. Load the first argument into r5 and get rid of the rest (including the
// receiver).
// 2. Load the first argument into r5.
{
Label no_arguments, done;
__ mr(r9, r3); // Store argc in r9.
__ cmpi(r3, Operand::Zero());
__ beq(&no_arguments);
__ subi(r3, r3, Operand(1));
__ ShiftLeftImm(r5, r3, Operand(kPointerSizeLog2));
__ LoadPUX(r5, MemOperand(sp, r5));
__ Drop(2);
__ LoadPX(r5, MemOperand(sp, r5));
__ b(&done);
__ bind(&no_arguments);
__ LoadRoot(r5, Heap::kempty_stringRootIndex);
__ Drop(1);
__ bind(&done);
}
......@@ -439,37 +470,50 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ blt(&done_convert);
__ bind(&convert);
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
FrameScope scope(masm, StackFrame::MANUAL);
ToStringStub stub(masm->isolate());
__ Push(r4, r6);
__ SmiTag(r9);
__ EnterBuiltinFrame(cp, r4, r9);
__ Push(r6);
__ mr(r3, r5);
__ CallStub(&stub);
__ mr(r5, r3);
__ Pop(r4, r6);
__ Pop(r6);
__ LeaveBuiltinFrame(cp, r4, r9);
__ SmiUntag(r9);
}
__ bind(&done_convert);
}
// 4. Check if new target and constructor differ.
Label new_object;
Label drop_frame_and_ret, new_object;
__ cmp(r4, r6);
__ bne(&new_object);
// 5. Allocate a JSValue wrapper for the string.
__ AllocateJSValue(r3, r4, r5, r7, r8, &new_object);
__ Ret();
__ b(&drop_frame_and_ret);
// 6. Fallback to the runtime to create new object.
__ bind(&new_object);
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
FrameScope scope(masm, StackFrame::MANUAL);
__ SmiTag(r9);
__ EnterBuiltinFrame(cp, r4, r9);
__ Push(r5); // first argument
FastNewObjectStub stub(masm->isolate());
__ CallStub(&stub);
__ Pop(r5);
__ LeaveBuiltinFrame(cp, r4, r9);
__ SmiUntag(r9);
}
__ StoreP(r5, FieldMemOperand(r3, JSValue::kValueOffset), r0);
__ Ret();
__ bind(&drop_frame_and_ret);
{
__ Drop(r9);
__ Ret(1);
}
}
......@@ -1827,9 +1871,8 @@ void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
{
FrameScope scope(masm, StackFrame::MANUAL);
__ push(r3);
__ PushStandardFrame(r4);
__ LoadSmiLiteral(r7, Smi::FromInt(0));
__ push(r7);
__ LoadSmiLiteral(r3, Smi::FromInt(0));
__ EnterBuiltinFrame(cp, r4, r3);
__ CallRuntime(Runtime::kThrowNotDateError);
}
}
......
......@@ -1072,6 +1072,49 @@ int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) {
return frame_ends;
}
void MacroAssembler::EnterBuiltinFrame(Register context, Register target,
Register argc) {
int fp_delta = 0;
mflr(r0);
if (FLAG_enable_embedded_constant_pool) {
if (target.is_valid()) {
Push(r0, fp, kConstantPoolRegister, context, target);
fp_delta = 3;
} else {
Push(r0, fp, kConstantPoolRegister, context);
fp_delta = 2;
}
} else {
if (target.is_valid()) {
Push(r0, fp, context, target);
fp_delta = 2;
} else {
Push(r0, fp, context);
fp_delta = 1;
}
}
addi(fp, sp, Operand(fp_delta * kPointerSize));
Push(argc);
}
void MacroAssembler::LeaveBuiltinFrame(Register context, Register target,
Register argc) {
Pop(argc);
if (FLAG_enable_embedded_constant_pool) {
if (target.is_valid()) {
Pop(r0, fp, kConstantPoolRegister, context, target);
} else {
Pop(r0, fp, kConstantPoolRegister, context);
}
} else {
if (target.is_valid()) {
Pop(r0, fp, context, target);
} else {
Pop(r0, fp, context);
}
}
mtlr(r0);
}
// ExitFrame layout (probably wrongish.. needs updating)
//
......
......@@ -1526,6 +1526,9 @@ class MacroAssembler : public Assembler {
// Returns the pc offset at which the frame ends.
int LeaveFrame(StackFrame::Type type, int stack_adjustment = 0);
void EnterBuiltinFrame(Register context, Register target, Register argc);
void LeaveBuiltinFrame(Register context, Register target, Register argc);
// Expects object in r3 and returns map with validated enum cache
// in r3. Assumes that any other register can be used as a scratch.
void CheckEnumCache(Label* call_runtime);
......
......@@ -165,14 +165,17 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
// Parameter is not a Number, use the ToNumber builtin to convert it.
DCHECK(!FLAG_enable_embedded_constant_pool);
FrameScope scope(masm, StackFrame::MANUAL);
__ PushStandardFrame(r3);
__ SmiTag(r2);
__ SmiTag(r6);
__ Push(r2, r6, r7);
__ EnterBuiltinFrame(cp, r3, r2);
__ Push(r6, r7);
__ LoadRR(r2, r4);
__ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ LoadRR(r4, r2);
__ Pop(r2, r6, r7);
__ Pop(r6, r7);
__ LeaveBuiltinFrame(cp, r3, r2);
__ SmiUntag(r6);
__ SmiUntag(r2);
{
// Restore the double accumulator value (d1).
Label done_restore;
......@@ -181,9 +184,6 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
__ LoadDouble(d1, FieldMemOperand(r7, HeapNumber::kValueOffset));
__ bind(&done_restore);
}
__ SmiUntag(r6);
__ SmiUntag(r2);
__ Pop(r14, fp, cp, r3);
}
__ b(&convert);
__ bind(&convert_number);
......@@ -232,26 +232,38 @@ void Builtins::Generate_NumberConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r2 : number of arguments
// -- r3 : constructor function
// -- cp : context
// -- lr : return address
// -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
// -- sp[argc * 4] : receiver
// -----------------------------------
// 1. Load the first argument into r2 and get rid of the rest (including the
// receiver).
// 1. Load the first argument into r2.
Label no_arguments;
{
__ LoadRR(r4, r2); // Store argc in r4.
__ CmpP(r2, Operand::Zero());
__ beq(&no_arguments);
__ SubP(r2, r2, Operand(1));
__ ShiftLeftP(r2, r2, Operand(kPointerSizeLog2));
__ la(sp, MemOperand(sp, r2));
__ LoadP(r2, MemOperand(sp));
__ Drop(2);
__ LoadP(r2, MemOperand(sp, r2));
}
// 2a. Convert the first argument to a number.
__ Jump(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
{
FrameScope scope(masm, StackFrame::MANUAL);
__ SmiTag(r4);
__ EnterBuiltinFrame(cp, r3, r4);
__ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ LeaveBuiltinFrame(cp, r3, r4);
__ SmiUntag(r4);
}
{
// Drop all arguments including the receiver.
__ Drop(r4);
__ Ret(1);
}
// 2b. No arguments, return +0.
__ bind(&no_arguments);
......@@ -273,21 +285,18 @@ void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
// 1. Make sure we operate in the context of the called function.
__ LoadP(cp, FieldMemOperand(r3, JSFunction::kContextOffset));
// 2. Load the first argument into r4 and get rid of the rest (including the
// receiver).
// 2. Load the first argument into r4.
{
Label no_arguments, done;
__ LoadRR(r8, r2); // Store argc in r8.
__ CmpP(r2, Operand::Zero());
__ beq(&no_arguments);
__ SubP(r2, r2, Operand(1));
__ ShiftLeftP(r4, r2, Operand(kPointerSizeLog2));
__ la(sp, MemOperand(sp, r4));
__ LoadP(r4, MemOperand(sp));
__ Drop(2);
__ LoadP(r4, MemOperand(sp, r4));
__ b(&done);
__ bind(&no_arguments);
__ LoadSmiLiteral(r4, Smi::FromInt(0));
__ Drop(1);
__ bind(&done);
}
......@@ -298,36 +307,49 @@ void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
__ CompareObjectType(r4, r6, r6, HEAP_NUMBER_TYPE);
__ beq(&done_convert);
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Push(r3, r5);
FrameScope scope(masm, StackFrame::MANUAL);
__ SmiTag(r8);
__ EnterBuiltinFrame(cp, r3, r8);
__ Push(r5);
__ LoadRR(r2, r4);
__ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ LoadRR(r4, r2);
__ Pop(r3, r5);
__ Pop(r5);
__ LeaveBuiltinFrame(cp, r3, r8);
__ SmiUntag(r8);
}
__ bind(&done_convert);
}
// 4. Check if new target and constructor differ.
Label new_object;
Label drop_frame_and_ret, new_object;
__ CmpP(r3, r5);
__ bne(&new_object);
// 5. Allocate a JSValue wrapper for the number.
__ AllocateJSValue(r2, r3, r4, r6, r7, &new_object);
__ Ret();
__ b(&drop_frame_and_ret);
// 6. Fallback to the runtime to create new object.
__ bind(&new_object);
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Push(r4); // first argument
FrameScope scope(masm, StackFrame::MANUAL);
FastNewObjectStub stub(masm->isolate());
__ SmiTag(r8);
__ EnterBuiltinFrame(cp, r3, r8);
__ Push(r4); // first argument
__ CallStub(&stub);
__ Pop(r4);
__ LeaveBuiltinFrame(cp, r3, r8);
__ SmiUntag(r8);
}
__ StoreP(r4, FieldMemOperand(r2, JSValue::kValueOffset), r0);
__ Ret();
__ bind(&drop_frame_and_ret);
{
__ Drop(r8);
__ Ret(1);
}
}
// static
......@@ -335,33 +357,32 @@ void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r2 : number of arguments
// -- r3 : constructor function
// -- cp : context
// -- lr : return address
// -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
// -- sp[argc * 4] : receiver
// -----------------------------------
// 1. Load the first argument into r2 and get rid of the rest (including the
// receiver).
// 1. Load the first argument into r2.
Label no_arguments;
{
__ LoadRR(r4, r2); // Store argc in r4
__ CmpP(r2, Operand::Zero());
__ beq(&no_arguments);
__ SubP(r2, r2, Operand(1));
__ ShiftLeftP(r2, r2, Operand(kPointerSizeLog2));
__ lay(sp, MemOperand(sp, r2));
__ LoadP(r2, MemOperand(sp));
__ Drop(2);
__ LoadP(r2, MemOperand(sp, r2));
}
// 2a. At least one argument, return r2 if it's a string, otherwise
// dispatch to appropriate conversion.
Label to_string, symbol_descriptive_string;
Label drop_frame_and_ret, to_string, symbol_descriptive_string;
{
__ JumpIfSmi(r2, &to_string);
STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE);
__ CompareObjectType(r2, r3, r3, FIRST_NONSTRING_TYPE);
__ CompareObjectType(r2, r5, r5, FIRST_NONSTRING_TYPE);
__ bgt(&to_string);
__ beq(&symbol_descriptive_string);
__ Ret();
__ b(&drop_frame_and_ret);
}
// 2b. No arguments, return the empty string (and pop the receiver).
......@@ -374,15 +395,29 @@ void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
// 3a. Convert r2 to a string.
__ bind(&to_string);
{
FrameScope scope(masm, StackFrame::MANUAL);
ToStringStub stub(masm->isolate());
__ TailCallStub(&stub);
__ SmiTag(r4);
__ EnterBuiltinFrame(cp, r3, r4);
__ CallStub(&stub);
__ LeaveBuiltinFrame(cp, r3, r4);
__ SmiUntag(r4);
}
__ b(&drop_frame_and_ret);
// 3b. Convert symbol in r2 to a string.
__ bind(&symbol_descriptive_string);
{
__ Drop(r4);
__ Drop(1);
__ Push(r2);
__ TailCallRuntime(Runtime::kSymbolDescriptiveString);
}
__ bind(&drop_frame_and_ret);
{
__ Drop(r4);
__ Ret(1);
}
}
// static
......@@ -391,6 +426,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
// -- r2 : number of arguments
// -- r3 : constructor function
// -- r5 : new target
// -- cp : context
// -- lr : return address
// -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
// -- sp[argc * 4] : receiver
......@@ -399,21 +435,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
// 1. Make sure we operate in the context of the called function.
__ LoadP(cp, FieldMemOperand(r3, JSFunction::kContextOffset));
// 2. Load the first argument into r4 and get rid of the rest (including the
// receiver).
// 2. Load the first argument into r4.
{
Label no_arguments, done;
__ LoadRR(r8, r2); // Store argc in r8.
__ CmpP(r2, Operand::Zero());
__ beq(&no_arguments);
__ SubP(r2, r2, Operand(1));
__ ShiftLeftP(r4, r2, Operand(kPointerSizeLog2));
__ lay(sp, MemOperand(sp, r4));
__ LoadP(r4, MemOperand(sp));
__ Drop(2);
__ LoadP(r4, MemOperand(sp, r4));
__ b(&done);
__ bind(&no_arguments);
__ LoadRoot(r4, Heap::kempty_stringRootIndex);
__ Drop(1);
__ bind(&done);
}
......@@ -425,37 +458,50 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ blt(&done_convert);
__ bind(&convert);
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
FrameScope scope(masm, StackFrame::MANUAL);
ToStringStub stub(masm->isolate());
__ Push(r3, r5);
__ SmiTag(r8);
__ EnterBuiltinFrame(cp, r3, r8);
__ Push(r5);
__ LoadRR(r2, r4);
__ CallStub(&stub);
__ LoadRR(r4, r2);
__ Pop(r3, r5);
__ Pop(r5);
__ LeaveBuiltinFrame(cp, r3, r8);
__ SmiUntag(r8);
}
__ bind(&done_convert);
}
// 4. Check if new target and constructor differ.
Label new_object;
Label drop_frame_and_ret, new_object;
__ CmpP(r3, r5);
__ bne(&new_object);
// 5. Allocate a JSValue wrapper for the string.
__ AllocateJSValue(r2, r3, r4, r6, r7, &new_object);
__ Ret();
__ b(&drop_frame_and_ret);
// 6. Fallback to the runtime to create new object.
__ bind(&new_object);
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Push(r4); // first argument
FrameScope scope(masm, StackFrame::MANUAL);
FastNewObjectStub stub(masm->isolate());
__ SmiTag(r8);
__ EnterBuiltinFrame(cp, r3, r8);
__ Push(r4); // first argument
__ CallStub(&stub);
__ Pop(r4);
__ LeaveBuiltinFrame(cp, r3, r8);
__ SmiUntag(r8);
}
__ StoreP(r4, FieldMemOperand(r2, JSValue::kValueOffset), r0);
__ Ret();
__ bind(&drop_frame_and_ret);
{
__ Drop(r8);
__ Ret(1);
}
}
static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
......@@ -1792,9 +1838,8 @@ void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
{
FrameScope scope(masm, StackFrame::MANUAL);
__ push(r2);
__ PushStandardFrame(r3);
__ LoadSmiLiteral(r6, Smi::FromInt(0));
__ push(r6);
__ LoadSmiLiteral(r2, Smi::FromInt(0));
__ EnterBuiltinFrame(cp, r3, r2);
__ CallRuntime(Runtime::kThrowNotDateError);
}
}
......
......@@ -1000,6 +1000,20 @@ int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) {
return frame_ends;
}
void MacroAssembler::EnterBuiltinFrame(Register context, Register target,
Register argc) {
CleanseP(r14);
Push(r14, fp, context, target);
la(fp, MemOperand(sp, 2 * kPointerSize));
Push(argc);
}
void MacroAssembler::LeaveBuiltinFrame(Register context, Register target,
Register argc) {
Pop(argc);
Pop(r14, fp, context, target);
}
// ExitFrame layout (probably wrongish.. needs updating)
//
// SP -> previousSP
......
......@@ -1792,6 +1792,9 @@ class MacroAssembler : public Assembler {
// Returns the pc offset at which the frame ends.
int LeaveFrame(StackFrame::Type type, int stack_adjustment = 0);
void EnterBuiltinFrame(Register context, Register target, Register argc);
void LeaveBuiltinFrame(Register context, Register target, Register argc);
// Expects object in r2 and returns map with validated enum cache
// in r2. Assumes that any other register can be used as a scratch.
void CheckEnumCache(Label* call_runtime);
......
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