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/arm64/builtins-arm64.cc b/src/arm64/builtins-arm64.cc
index be372e6..e16897a 100644
--- a/src/arm64/builtins-arm64.cc
+++ b/src/arm64/builtins-arm64.cc
@@ -32,10 +32,7 @@
__ LoadNativeContextSlot(Context::INTERNAL_ARRAY_FUNCTION_INDEX, result);
}
-
-void Builtins::Generate_Adaptor(MacroAssembler* masm,
- CFunctionId id,
- BuiltinExtraArguments extra_args) {
+void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
// ----------- S t a t e -------------
// -- x0 : number of arguments excluding receiver
// -- x1 : target
@@ -54,23 +51,8 @@
__ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset));
// Insert extra arguments.
- int num_extra_args = 0;
- switch (extra_args) {
- case BuiltinExtraArguments::kTarget:
- __ Push(x1);
- ++num_extra_args;
- break;
- case BuiltinExtraArguments::kNewTarget:
- __ Push(x3);
- ++num_extra_args;
- break;
- case BuiltinExtraArguments::kTargetAndNewTarget:
- __ Push(x1, x3);
- num_extra_args += 2;
- break;
- case BuiltinExtraArguments::kNone:
- break;
- }
+ const int num_extra_args = 2;
+ __ Push(x1, x3);
// JumpToExternalReference expects x0 to contain the number of arguments
// including the receiver and the extra arguments.
@@ -141,6 +123,8 @@
void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
// ----------- S t a t e -------------
// -- x0 : number of arguments
+ // -- x1 : function
+ // -- cp : context
// -- lr : return address
// -- sp[(argc - n) * 8] : arg[n] (zero-based)
// -- sp[(argc + 1) * 8] : receiver
@@ -152,9 +136,9 @@
: Heap::kMinusInfinityValueRootIndex;
// Load the accumulator with the default return value (either -Infinity or
- // +Infinity), with the tagged value in x1 and the double value in d1.
- __ LoadRoot(x1, root_index);
- __ Ldr(d1, FieldMemOperand(x1, HeapNumber::kValueOffset));
+ // +Infinity), with the tagged value in x5 and the double value in d5.
+ __ LoadRoot(x5, root_index);
+ __ Ldr(d5, FieldMemOperand(x5, HeapNumber::kValueOffset));
// Remember how many slots to drop (including the receiver).
__ Add(x4, x0, 1);
@@ -170,31 +154,34 @@
__ Peek(x2, Operand(x0, LSL, kPointerSizeLog2));
// 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_smi, convert_number, done_convert;
__ JumpIfSmi(x2, &convert_smi);
__ JumpIfHeapNumber(x2, &convert_number);
{
- // Parameter is not a Number, use the ToNumberStub to convert it.
- FrameScope scope(masm, StackFrame::INTERNAL);
+ // Parameter is not a Number, use the ToNumber builtin to convert it.
+ FrameScope scope(masm, StackFrame::MANUAL);
+ __ Push(lr, fp);
+ __ Move(fp, jssp);
+ __ Push(cp, x1);
__ SmiTag(x0);
__ SmiTag(x4);
- __ Push(x0, x1, x4);
+ __ Push(x0, x5, x4);
__ Mov(x0, x2);
- ToNumberStub stub(masm->isolate());
- __ CallStub(&stub);
+ __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ Mov(x2, x0);
- __ Pop(x4, x1, x0);
+ __ Pop(x4, x5, x0);
{
- // Restore the double accumulator value (d1).
+ // Restore the double accumulator value (d5).
Label done_restore;
- __ SmiUntagToDouble(d1, x1, kSpeculativeUntag);
- __ JumpIfSmi(x1, &done_restore);
- __ Ldr(d1, FieldMemOperand(x1, HeapNumber::kValueOffset));
+ __ SmiUntagToDouble(d5, x5, kSpeculativeUntag);
+ __ JumpIfSmi(x5, &done_restore);
+ __ Ldr(d5, FieldMemOperand(x5, HeapNumber::kValueOffset));
__ Bind(&done_restore);
}
__ SmiUntag(x4);
__ SmiUntag(x0);
+ __ Pop(x1, cp, fp, lr);
}
__ AssertNumber(x2);
__ JumpIfSmi(x2, &convert_smi);
@@ -209,22 +196,22 @@
// We can use a single fmin/fmax for the operation itself, but we then need
// to work out which HeapNumber (or smi) the result came from.
- __ Fmov(x11, d1);
+ __ Fmov(x11, d5);
if (kind == MathMaxMinKind::kMin) {
- __ Fmin(d1, d1, d2);
+ __ Fmin(d5, d5, d2);
} else {
DCHECK(kind == MathMaxMinKind::kMax);
- __ Fmax(d1, d1, d2);
+ __ Fmax(d5, d5, d2);
}
- __ Fmov(x10, d1);
+ __ Fmov(x10, d5);
__ Cmp(x10, x11);
- __ Csel(x1, x1, x2, eq);
+ __ Csel(x5, x5, x2, eq);
__ B(&loop);
}
__ Bind(&done_loop);
- __ Mov(x0, x1);
__ Drop(x4);
+ __ Mov(x0, x5);
__ Ret();
}
@@ -250,8 +237,7 @@
}
// 2a. Convert first argument to number.
- ToNumberStub stub(masm->isolate());
- __ TailCallStub(&stub);
+ __ Jump(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
// 2b. No arguments, return +0 (already in x0).
__ Bind(&no_arguments);
@@ -299,8 +285,7 @@
FrameScope scope(masm, StackFrame::INTERNAL);
__ Push(x1, x3);
__ Move(x0, x2);
- ToNumberStub stub(masm->isolate());
- __ CallStub(&stub);
+ __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ Move(x2, x0);
__ Pop(x3, x1);
}
@@ -715,8 +700,8 @@
__ AssertGeneratorObject(x1);
// Store input value into generator object.
- __ Str(x0, FieldMemOperand(x1, JSGeneratorObject::kInputOffset));
- __ RecordWriteField(x1, JSGeneratorObject::kInputOffset, x0, x3,
+ __ Str(x0, FieldMemOperand(x1, JSGeneratorObject::kInputOrDebugPosOffset));
+ __ RecordWriteField(x1, JSGeneratorObject::kInputOrDebugPosOffset, x0, x3,
kLRHasNotBeenSaved, kDontSaveFPRegs);
// Store resume mode into generator object.
@@ -727,20 +712,23 @@
__ Ldr(x4, FieldMemOperand(x1, JSGeneratorObject::kFunctionOffset));
// Flood function if we are stepping.
- Label skip_flooding;
- ExternalReference step_in_enabled =
- ExternalReference::debug_step_in_enabled_address(masm->isolate());
- __ Mov(x10, Operand(step_in_enabled));
- __ Ldrb(x10, MemOperand(x10));
- __ CompareAndBranch(x10, Operand(0), eq, &skip_flooding);
- {
- FrameScope scope(masm, StackFrame::INTERNAL);
- __ Push(x1, x2, x4);
- __ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
- __ Pop(x2, x1);
- __ Ldr(x4, FieldMemOperand(x1, 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(x10, Operand(last_step_action));
+ __ Ldrsb(x10, MemOperand(x10));
+ __ CompareAndBranch(x10, Operand(StepIn), ge, &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(x10, Operand(debug_suspended_generator));
+ __ Ldr(x10, MemOperand(x10));
+ __ CompareAndBranch(x10, Operand(x1), eq,
+ &prepare_step_in_suspended_generator);
+ __ Bind(&stepping_prepared);
// Push receiver.
__ Ldr(x5, FieldMemOperand(x1, JSGeneratorObject::kReceiverOffset));
@@ -775,9 +763,8 @@
// New-style (ignition/turbofan) generator object
{
__ Ldr(x0, FieldMemOperand(x4, JSFunction::kSharedFunctionInfoOffset));
- __ Ldr(x0,
+ __ Ldr(w0,
FieldMemOperand(x0, SharedFunctionInfo::kFormalParameterCountOffset));
- __ SmiUntag(x0);
// We abuse new.target both to indicate that this is a resume call and to
// pass in the generator object. In ordinary calls, new.target is always
// undefined because generator functions are non-constructable.
@@ -829,6 +816,26 @@
__ Move(x0, x1); // Continuation expects generator object in x0.
__ Br(x10);
}
+
+ __ Bind(&prepare_step_in_if_stepping);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(x1, x2, x4);
+ __ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
+ __ Pop(x2, x1);
+ __ Ldr(x4, FieldMemOperand(x1, JSGeneratorObject::kFunctionOffset));
+ }
+ __ B(&stepping_prepared);
+
+ __ Bind(&prepare_step_in_suspended_generator);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(x1, x2);
+ __ CallRuntime(Runtime::kDebugPrepareStepInSuspendedGenerator);
+ __ Pop(x2, x1);
+ __ Ldr(x4, FieldMemOperand(x1, JSGeneratorObject::kFunctionOffset));
+ }
+ __ B(&stepping_prepared);
}
enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt };
@@ -963,6 +970,22 @@
Generate_JSEntryTrampolineHelper(masm, true);
}
+static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch) {
+ Register args_count = scratch;
+
+ // Get the arguments + receiver count.
+ __ ldr(args_count,
+ MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
+ __ Ldr(args_count.W(),
+ FieldMemOperand(args_count, BytecodeArray::kParameterSizeOffset));
+
+ // Leave the frame (also dropping the register file).
+ __ LeaveFrame(StackFrame::JAVA_SCRIPT);
+
+ // Drop receiver + arguments.
+ __ Drop(args_count, 1);
+}
+
// Generate code for entering a JS function with the interpreter.
// On entry to the function the receiver and arguments have been pushed on the
// stack left to right. The actual argument count matches the formal parameter
@@ -1064,16 +1087,7 @@
masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
// The return value is in x0.
-
- // Get the arguments + reciever count.
- __ ldr(x1, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
- __ Ldr(w1, FieldMemOperand(x1, BytecodeArray::kParameterSizeOffset));
-
- // Leave the frame (also dropping the register file).
- __ LeaveFrame(StackFrame::JAVA_SCRIPT);
-
- // Drop receiver + arguments and return.
- __ Drop(x1, 1);
+ LeaveInterpreterFrame(masm, x2);
__ Ret();
// Load debug copy of the bytecode array.
@@ -1095,6 +1109,31 @@
__ Jump(x7);
}
+void Builtins::Generate_InterpreterMarkBaselineOnReturn(MacroAssembler* masm) {
+ // Save the function and context for call to CompileBaseline.
+ __ ldr(x1, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
+ __ ldr(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, x2);
+
+ {
+ FrameScope frame_scope(masm, StackFrame::INTERNAL);
+ // Push return value.
+ __ push(x0);
+
+ // Push function as argument and compile for baseline.
+ __ push(x1);
+ __ CallRuntime(Runtime::kCompileBaseline);
+
+ // Restore return value.
+ __ pop(x0);
+ }
+ __ Ret();
+}
+
// static
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
MacroAssembler* masm, TailCallMode tail_call_mode) {
@@ -1255,13 +1294,31 @@
const int bailout_id = BailoutId::None().ToInt();
__ Cmp(temp, Operand(Smi::FromInt(bailout_id)));
__ B(ne, &loop_bottom);
+
// Literals available?
+ Label got_literals, maybe_cleared_weakcell;
+ Register temp2 = x7;
__ Ldr(temp, FieldMemOperand(array_pointer,
SharedFunctionInfo::kOffsetToPreviousLiterals));
+ // temp contains either a WeakCell pointing to the literals array or the
+ // literals array directly.
+ STATIC_ASSERT(WeakCell::kValueOffset == FixedArray::kLengthOffset);
+ __ Ldr(temp2, FieldMemOperand(temp, WeakCell::kValueOffset));
+ __ JumpIfSmi(temp2, &maybe_cleared_weakcell);
+ // temp2 is a pointer, therefore temp is a WeakCell pointing to a literals
+ // array.
__ Ldr(temp, FieldMemOperand(temp, WeakCell::kValueOffset));
- __ JumpIfSmi(temp, &gotta_call_runtime);
+ __ jmp(&got_literals);
+
+ // r4 is a smi. If it's 0, then we are looking at a cleared WeakCell
+ // around the literals array, and we should visit the runtime. If it's > 0,
+ // then temp already contains the literals array.
+ __ bind(&maybe_cleared_weakcell);
+ __ Cmp(temp2, Operand(Smi::FromInt(0)));
+ __ B(eq, &gotta_call_runtime);
// Save the literals in the closure.
+ __ bind(&got_literals);
__ Str(temp, FieldMemOperand(closure, JSFunction::kLiteralsOffset));
__ RecordWriteField(closure, JSFunction::kLiteralsOffset, temp, x7,
kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
@@ -1671,6 +1728,9 @@
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
// ----------- S t a t e -------------
+ // -- x0 : number of arguments
+ // -- x1 : function
+ // -- cp : context
// -- lr : return address
// -- jssp[0] : receiver
// -----------------------------------
@@ -1681,7 +1741,7 @@
{
__ Pop(x0);
__ JumpIfSmi(x0, &receiver_not_date);
- __ JumpIfNotObjectType(x0, x1, x2, JS_DATE_TYPE, &receiver_not_date);
+ __ JumpIfNotObjectType(x0, x2, x3, JS_DATE_TYPE, &receiver_not_date);
}
// 2. Load the specified date field, falling back to the runtime as necessary.
@@ -1709,7 +1769,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(x0, lr, fp);
+ __ Move(fp, jssp);
+ __ Push(cp, x1);
+ __ Push(Smi::FromInt(0));
+ __ CallRuntime(Runtime::kThrowNotDateError);
+ }
}
// static
@@ -2711,6 +2778,82 @@
__ TailCallRuntime(Runtime::kAllocateInTargetSpace);
}
+// static
+void Builtins::Generate_StringToNumber(MacroAssembler* masm) {
+ // The StringToNumber stub takes one argument in x0.
+ __ AssertString(x0);
+
+ // Check if string has a cached array index.
+ Label runtime;
+ __ Ldr(x2, FieldMemOperand(x0, String::kHashFieldOffset));
+ __ Tst(x2, Operand(String::kContainsCachedArrayIndexMask));
+ __ B(ne, &runtime);
+ __ IndexFromHash(x2, x0);
+ __ Ret();
+
+ __ Bind(&runtime);
+ {
+ FrameScope frame(masm, StackFrame::INTERNAL);
+ // Push argument.
+ __ Push(x0);
+ // 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 x0.
+ Label not_smi;
+ __ JumpIfNotSmi(x0, ¬_smi);
+ __ Ret();
+ __ Bind(¬_smi);
+
+ Label not_heap_number;
+ __ CompareObjectType(x0, x1, x1, HEAP_NUMBER_TYPE);
+ // x0: receiver
+ // x1: receiver instance type
+ __ B(ne, ¬_heap_number);
+ __ Ret();
+ __ Bind(¬_heap_number);
+
+ __ Jump(masm->isolate()->builtins()->NonNumberToNumber(),
+ RelocInfo::CODE_TARGET);
+}
+
+// static
+void Builtins::Generate_NonNumberToNumber(MacroAssembler* masm) {
+ // The NonNumberToNumber stub takes one argument in x0.
+ __ AssertNotNumber(x0);
+
+ Label not_string;
+ __ CompareObjectType(x0, x1, x1, FIRST_NONSTRING_TYPE);
+ // x0: receiver
+ // x1: receiver instance type
+ __ B(hs, ¬_string);
+ __ Jump(masm->isolate()->builtins()->StringToNumber(),
+ RelocInfo::CODE_TARGET);
+ __ Bind(¬_string);
+
+ Label not_oddball;
+ __ Cmp(x1, ODDBALL_TYPE);
+ __ B(ne, ¬_oddball);
+ __ Ldr(x0, FieldMemOperand(x0, Oddball::kToNumberOffset));
+ __ Ret();
+ __ Bind(¬_oddball);
+ {
+ FrameScope frame(masm, StackFrame::INTERNAL);
+ // Push argument.
+ __ Push(x0);
+ // 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) {
ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline");
// ----------- S t a t e -------------