Merge V8 5.3.332.45. DO NOT MERGE
Test: Manual
FPIIM-449
Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/src/ppc/builtins-ppc.cc b/src/ppc/builtins-ppc.cc
index a6263cd..c3c2b84 100644
--- a/src/ppc/builtins-ppc.cc
+++ b/src/ppc/builtins-ppc.cc
@@ -17,8 +17,7 @@
#define __ ACCESS_MASM(masm)
-void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id,
- BuiltinExtraArguments extra_args) {
+void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
// ----------- S t a t e -------------
// -- r3 : number of arguments excluding receiver
// -- r4 : target
@@ -37,23 +36,8 @@
__ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
// Insert extra arguments.
- int num_extra_args = 0;
- switch (extra_args) {
- case BuiltinExtraArguments::kTarget:
- __ Push(r4);
- ++num_extra_args;
- break;
- case BuiltinExtraArguments::kNewTarget:
- __ Push(r6);
- ++num_extra_args;
- break;
- case BuiltinExtraArguments::kTargetAndNewTarget:
- __ Push(r4, r6);
- num_extra_args += 2;
- break;
- case BuiltinExtraArguments::kNone:
- break;
- }
+ const int num_extra_args = 2;
+ __ Push(r4, r6);
// JumpToExternalReference expects r3 to contain the number of arguments
// including the receiver and the extra arguments.
@@ -139,6 +123,8 @@
void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
// ----------- S t a t e -------------
// -- r3 : number of arguments
+ // -- r4 : function
+ // -- cp : context
// -- lr : return address
// -- sp[(argc - n) * 8] : arg[n] (zero-based)
// -- sp[(argc + 1) * 8] : receiver
@@ -150,58 +136,69 @@
DoubleRegister const reg = (kind == MathMaxMinKind::kMin) ? d2 : d1;
// Load the accumulator with the default return value (either -Infinity or
- // +Infinity), with the tagged value in r4 and the double value in d1.
- __ LoadRoot(r4, root_index);
- __ lfd(d1, FieldMemOperand(r4, HeapNumber::kValueOffset));
+ // +Infinity), with the tagged value in r8 and the double value in d1.
+ __ LoadRoot(r8, root_index);
+ __ lfd(d1, FieldMemOperand(r8, HeapNumber::kValueOffset));
// Setup state for loop
// r5: address of arg[0] + kPointerSize
// r6: number of slots to drop at exit (arguments + receiver)
- __ ShiftLeftImm(r5, r3, Operand(kPointerSizeLog2));
- __ add(r5, sp, r5);
- __ addi(r6, r3, Operand(1));
+ __ addi(r7, r3, Operand(1));
Label done_loop, loop;
__ bind(&loop);
{
// Check if all parameters done.
- __ cmpl(r5, sp);
- __ ble(&done_loop);
+ __ subi(r3, r3, Operand(1));
+ __ cmpi(r3, Operand::Zero());
+ __ blt(&done_loop);
- // Load the next parameter tagged value into r3.
- __ LoadPU(r3, MemOperand(r5, -kPointerSize));
+ // Load the next parameter tagged value into r5.
+ __ ShiftLeftImm(r5, r3, Operand(kPointerSizeLog2));
+ __ LoadPX(r5, MemOperand(sp, r5));
// Load the double value of the parameter into d2, maybe converting the
- // parameter to a number first using the ToNumberStub if necessary.
+ // parameter to a number first using the ToNumber builtin if necessary.
Label convert, convert_smi, convert_number, done_convert;
__ bind(&convert);
- __ JumpIfSmi(r3, &convert_smi);
- __ LoadP(r7, FieldMemOperand(r3, HeapObject::kMapOffset));
- __ JumpIfRoot(r7, Heap::kHeapNumberMapRootIndex, &convert_number);
+ __ JumpIfSmi(r5, &convert_smi);
+ __ LoadP(r6, FieldMemOperand(r5, HeapObject::kMapOffset));
+ __ JumpIfRoot(r6, Heap::kHeapNumberMapRootIndex, &convert_number);
{
- // Parameter is not a Number, use the ToNumberStub to convert it.
- FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
- __ SmiTag(r6);
- __ Push(r4, r5, r6);
- ToNumberStub stub(masm->isolate());
- __ CallStub(&stub);
- __ Pop(r4, r5, r6);
- __ SmiUntag(r6);
+ // 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);
+ __ mr(r3, r5);
+ __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
+ __ mr(r5, r3);
+ __ Pop(r3, r7, r8);
{
// Restore the double accumulator value (d1).
Label done_restore;
- __ SmiToDouble(d1, r4);
- __ JumpIfSmi(r4, &done_restore);
- __ lfd(d1, FieldMemOperand(r4, HeapNumber::kValueOffset));
+ __ SmiToDouble(d1, r8);
+ __ JumpIfSmi(r8, &done_restore);
+ __ 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);
- __ lfd(d2, FieldMemOperand(r3, HeapNumber::kValueOffset));
+ __ lfd(d2, FieldMemOperand(r5, HeapNumber::kValueOffset));
__ b(&done_convert);
__ bind(&convert_smi);
- __ SmiToDouble(d2, r3);
+ __ SmiToDouble(d2, r5);
__ bind(&done_convert);
// Perform the actual comparison with the accumulator value on the left hand
@@ -213,26 +210,26 @@
__ b(CommuteCondition(cond_done), &compare_swap);
// Left and right hand side are equal, check for -0 vs. +0.
- __ TestDoubleIsMinusZero(reg, r7, r8);
+ __ TestDoubleIsMinusZero(reg, r9, r0);
__ bne(&loop);
// Update accumulator. Result is on the right hand side.
__ bind(&compare_swap);
__ fmr(d1, d2);
- __ mr(r4, r3);
+ __ mr(r8, r5);
__ b(&loop);
// At least one side is NaN, which means that the result will be NaN too.
// We still need to visit the rest of the arguments.
__ bind(&compare_nan);
- __ LoadRoot(r4, Heap::kNanValueRootIndex);
- __ lfd(d1, FieldMemOperand(r4, HeapNumber::kValueOffset));
+ __ LoadRoot(r8, Heap::kNanValueRootIndex);
+ __ lfd(d1, FieldMemOperand(r8, HeapNumber::kValueOffset));
__ b(&loop);
}
__ bind(&done_loop);
- __ mr(r3, r4);
- __ Drop(r6);
+ __ mr(r3, r8);
+ __ Drop(r7);
__ Ret();
}
@@ -259,8 +256,7 @@
}
// 2a. Convert the first argument to a number.
- ToNumberStub stub(masm->isolate());
- __ TailCallStub(&stub);
+ __ Jump(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
// 2b. No arguments, return +0.
__ bind(&no_arguments);
@@ -310,8 +306,7 @@
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Push(r4, r6);
__ mr(r3, r5);
- ToNumberStub stub(masm->isolate());
- __ CallStub(&stub);
+ __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ mr(r5, r3);
__ Pop(r4, r6);
}
@@ -711,8 +706,9 @@
__ AssertGeneratorObject(r4);
// Store input value into generator object.
- __ StoreP(r3, FieldMemOperand(r4, JSGeneratorObject::kInputOffset), r0);
- __ RecordWriteField(r4, JSGeneratorObject::kInputOffset, r3, r6,
+ __ StoreP(r3, FieldMemOperand(r4, JSGeneratorObject::kInputOrDebugPosOffset),
+ r0);
+ __ RecordWriteField(r4, JSGeneratorObject::kInputOrDebugPosOffset, r3, r6,
kLRHasNotBeenSaved, kDontSaveFPRegs);
// Store resume mode into generator object.
@@ -723,21 +719,27 @@
__ LoadP(r7, FieldMemOperand(r4, JSGeneratorObject::kFunctionOffset));
// Flood function if we are stepping.
- Label skip_flooding;
- ExternalReference step_in_enabled =
- ExternalReference::debug_step_in_enabled_address(masm->isolate());
- __ mov(ip, Operand(step_in_enabled));
- __ lbz(ip, MemOperand(ip));
- __ cmpi(ip, Operand::Zero());
- __ beq(&skip_flooding);
- {
- FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
- __ Push(r4, r5, r7);
- __ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
- __ Pop(r4, r5);
- __ LoadP(r7, FieldMemOperand(r4, JSGeneratorObject::kFunctionOffset));
- }
- __ bind(&skip_flooding);
+ Label prepare_step_in_if_stepping, prepare_step_in_suspended_generator;
+ Label stepping_prepared;
+ ExternalReference last_step_action =
+ ExternalReference::debug_last_step_action_address(masm->isolate());
+ STATIC_ASSERT(StepFrame > StepIn);
+ __ mov(ip, Operand(last_step_action));
+ __ LoadByte(ip, MemOperand(ip), r0);
+ __ extsb(ip, ip);
+ __ cmpi(ip, Operand(StepIn));
+ __ bge(&prepare_step_in_if_stepping);
+
+ // Flood function if we need to continue stepping in the suspended generator.
+
+ ExternalReference debug_suspended_generator =
+ ExternalReference::debug_suspended_generator_address(masm->isolate());
+
+ __ mov(ip, Operand(debug_suspended_generator));
+ __ LoadP(ip, MemOperand(ip));
+ __ cmp(ip, r4);
+ __ beq(&prepare_step_in_suspended_generator);
+ __ bind(&stepping_prepared);
// Push receiver.
__ LoadP(ip, FieldMemOperand(r4, JSGeneratorObject::kReceiverOffset));
@@ -843,6 +845,26 @@
__ Jump(r6);
}
}
+
+ __ bind(&prepare_step_in_if_stepping);
+ {
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+ __ Push(r4, r5, r7);
+ __ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
+ __ Pop(r4, r5);
+ __ LoadP(r7, FieldMemOperand(r4, JSGeneratorObject::kFunctionOffset));
+ }
+ __ b(&stepping_prepared);
+
+ __ bind(&prepare_step_in_suspended_generator);
+ {
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+ __ Push(r4, r5);
+ __ CallRuntime(Runtime::kDebugPrepareStepInSuspendedGenerator);
+ __ Pop(r4, r5);
+ __ LoadP(r7, FieldMemOperand(r4, JSGeneratorObject::kFunctionOffset));
+ }
+ __ b(&stepping_prepared);
}
void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
@@ -968,6 +990,20 @@
Generate_JSEntryTrampolineHelper(masm, true);
}
+static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch) {
+ Register args_count = scratch;
+
+ // Get the arguments + receiver count.
+ __ LoadP(args_count,
+ MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
+ __ lwz(args_count,
+ FieldMemOperand(args_count, BytecodeArray::kParameterSizeOffset));
+
+ // Leave the frame (also dropping the register file).
+ __ LeaveFrame(StackFrame::JAVA_SCRIPT);
+
+ __ add(sp, sp, args_count);
+}
// Generate code for entering a JS function with the interpreter.
// On entry to the function the receiver and arguments have been pushed on the
@@ -1077,15 +1113,7 @@
masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
// The return value is in r3.
-
- // Get the arguments + reciever count.
- __ LoadP(r5, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
- __ lwz(r5, FieldMemOperand(r5, BytecodeArray::kParameterSizeOffset));
-
- // Leave the frame (also dropping the register file).
- __ LeaveFrame(StackFrame::JAVA_SCRIPT);
-
- __ add(sp, sp, r5);
+ LeaveInterpreterFrame(masm, r5);
__ blr();
// If the bytecode array is no longer present, then the underlying function
@@ -1101,6 +1129,30 @@
__ JumpToJSEntry(r7);
}
+void Builtins::Generate_InterpreterMarkBaselineOnReturn(MacroAssembler* masm) {
+ // Save the function and context for call to CompileBaseline.
+ __ LoadP(r4, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
+ __ LoadP(kContextRegister,
+ MemOperand(fp, StandardFrameConstants::kContextOffset));
+
+ // Leave the frame before recompiling for baseline so that we don't count as
+ // an activation on the stack.
+ LeaveInterpreterFrame(masm, r5);
+
+ {
+ FrameScope frame_scope(masm, StackFrame::INTERNAL);
+ // Push return value.
+ __ push(r3);
+
+ // Push function as argument and compile for baseline.
+ __ push(r4);
+ __ CallRuntime(Runtime::kCompileBaseline);
+
+ // Restore return value.
+ __ pop(r3);
+ }
+ __ blr();
+}
static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index,
Register count, Register scratch) {
@@ -1687,6 +1739,9 @@
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
// ----------- S t a t e -------------
+ // -- r3 : number of arguments
+ // -- r4 : function
+ // -- cp : context
// -- lr : return address
// -- sp[0] : receiver
// -----------------------------------
@@ -1696,7 +1751,7 @@
{
__ Pop(r3);
__ JumpIfSmi(r3, &receiver_not_date);
- __ CompareObjectType(r3, r4, r5, JS_DATE_TYPE);
+ __ CompareObjectType(r3, r5, r6, JS_DATE_TYPE);
__ bne(&receiver_not_date);
}
@@ -1726,7 +1781,14 @@
// 3. Raise a TypeError if the receiver is not a date.
__ bind(&receiver_not_date);
- __ TailCallRuntime(Runtime::kThrowNotDateError);
+ {
+ FrameScope scope(masm, StackFrame::MANUAL);
+ __ push(r3);
+ __ PushStandardFrame(r4);
+ __ LoadSmiLiteral(r7, Smi::FromInt(0));
+ __ push(r7);
+ __ CallRuntime(Runtime::kThrowNotDateError);
+ }
}
// static
@@ -2696,6 +2758,76 @@
__ TailCallRuntime(Runtime::kAllocateInTargetSpace);
}
+// static
+void Builtins::Generate_StringToNumber(MacroAssembler* masm) {
+ // The StringToNumber stub takes one argument in r3.
+ __ AssertString(r3);
+
+ // Check if string has a cached array index.
+ Label runtime;
+ __ lwz(r5, FieldMemOperand(r3, String::kHashFieldOffset));
+ __ And(r0, r5, Operand(String::kContainsCachedArrayIndexMask), SetRC);
+ __ bne(&runtime, cr0);
+ __ IndexFromHash(r5, r3);
+ __ blr();
+
+ __ bind(&runtime);
+ {
+ FrameScope frame(masm, StackFrame::INTERNAL);
+ // Push argument.
+ __ push(r3);
+ // We cannot use a tail call here because this builtin can also be called
+ // from wasm.
+ __ CallRuntime(Runtime::kStringToNumber);
+ }
+ __ Ret();
+}
+
+// static
+void Builtins::Generate_ToNumber(MacroAssembler* masm) {
+ // The ToNumber stub takes one argument in r3.
+ STATIC_ASSERT(kSmiTag == 0);
+ __ TestIfSmi(r3, r0);
+ __ Ret(eq, cr0);
+
+ __ CompareObjectType(r3, r4, r4, HEAP_NUMBER_TYPE);
+ // r3: receiver
+ // r4: receiver instance type
+ __ Ret(eq);
+
+ __ Jump(masm->isolate()->builtins()->NonNumberToNumber(),
+ RelocInfo::CODE_TARGET);
+}
+
+// static
+void Builtins::Generate_NonNumberToNumber(MacroAssembler* masm) {
+ // The NonNumberToNumber stub takes one argument in r3.
+ __ AssertNotNumber(r3);
+
+ __ CompareObjectType(r3, r4, r4, FIRST_NONSTRING_TYPE);
+ // r3: receiver
+ // r4: receiver instance type
+ __ Jump(masm->isolate()->builtins()->StringToNumber(), RelocInfo::CODE_TARGET,
+ lt);
+
+ Label not_oddball;
+ __ cmpi(r4, Operand(ODDBALL_TYPE));
+ __ bne(¬_oddball);
+ __ LoadP(r3, FieldMemOperand(r3, Oddball::kToNumberOffset));
+ __ blr();
+ __ bind(¬_oddball);
+
+ {
+ FrameScope frame(masm, StackFrame::INTERNAL);
+ // Push argument.
+ __ push(r3);
+ // We cannot use a tail call here because this builtin can also be called
+ // from wasm.
+ __ CallRuntime(Runtime::kToNumber);
+ }
+ __ Ret();
+}
+
void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : actual number of arguments