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/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 419ee0f..fb43324 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -15,10 +15,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 -------------
// -- rax : number of arguments excluding receiver
// -- rdi : target
@@ -37,20 +34,13 @@
// ordinary functions).
__ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
- // Insert extra arguments.
- int num_extra_args = 0;
- if (extra_args != BuiltinExtraArguments::kNone) {
- __ PopReturnAddressTo(kScratchRegister);
- if (extra_args & BuiltinExtraArguments::kTarget) {
- ++num_extra_args;
- __ Push(rdi);
- }
- if (extra_args & BuiltinExtraArguments::kNewTarget) {
- ++num_extra_args;
- __ Push(rdx);
- }
- __ PushReturnAddressFrom(kScratchRegister);
- }
+ // Unconditionally insert the target and new target as extra arguments. They
+ // will be used by stack frame iterators when constructing the stack trace.
+ const int num_extra_args = 2;
+ __ PopReturnAddressTo(kScratchRegister);
+ __ Push(rdi);
+ __ Push(rdx);
+ __ PushReturnAddressFrom(kScratchRegister);
// JumpToExternalReference expects rax to contain the number of arguments
// including the receiver and the extra arguments.
@@ -468,8 +458,8 @@
__ AssertGeneratorObject(rbx);
// Store input value into generator object.
- __ movp(FieldOperand(rbx, JSGeneratorObject::kInputOffset), rax);
- __ RecordWriteField(rbx, JSGeneratorObject::kInputOffset, rax, rcx,
+ __ movp(FieldOperand(rbx, JSGeneratorObject::kInputOrDebugPosOffset), rax);
+ __ RecordWriteField(rbx, JSGeneratorObject::kInputOrDebugPosOffset, rax, rcx,
kDontSaveFPRegs);
// Store resume mode into generator object.
@@ -480,23 +470,23 @@
__ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset));
// Flood function if we are stepping.
- Label skip_flooding;
- ExternalReference step_in_enabled =
- ExternalReference::debug_step_in_enabled_address(masm->isolate());
- Operand step_in_enabled_operand = masm->ExternalOperand(step_in_enabled);
- __ cmpb(step_in_enabled_operand, Immediate(0));
- __ j(equal, &skip_flooding);
- {
- FrameScope scope(masm, StackFrame::INTERNAL);
- __ Push(rbx);
- __ Push(rdx);
- __ Push(rdi);
- __ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
- __ Pop(rdx);
- __ Pop(rbx);
- __ movp(rdi, FieldOperand(rbx, 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());
+ Operand last_step_action_operand = masm->ExternalOperand(last_step_action);
+ STATIC_ASSERT(StepFrame > StepIn);
+ __ cmpb(last_step_action_operand, Immediate(StepIn));
+ __ j(greater_equal, &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());
+ Operand debug_suspended_generator_operand =
+ masm->ExternalOperand(debug_suspended_generator);
+ __ cmpp(rbx, debug_suspended_generator_operand);
+ __ j(equal, &prepare_step_in_suspended_generator);
+ __ bind(&stepping_prepared);
// Pop return address.
__ PopReturnAddressTo(rax);
@@ -596,6 +586,51 @@
__ movp(rax, rbx); // Continuation expects generator object in rax.
__ jmp(rdx);
}
+
+ __ bind(&prepare_step_in_if_stepping);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(rbx);
+ __ Push(rdx);
+ __ Push(rdi);
+ __ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
+ __ Pop(rdx);
+ __ Pop(rbx);
+ __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset));
+ }
+ __ jmp(&stepping_prepared);
+
+ __ bind(&prepare_step_in_suspended_generator);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(rbx);
+ __ Push(rdx);
+ __ CallRuntime(Runtime::kDebugPrepareStepInSuspendedGenerator);
+ __ Pop(rdx);
+ __ Pop(rbx);
+ __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset));
+ }
+ __ jmp(&stepping_prepared);
+}
+
+static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1,
+ Register scratch2) {
+ Register args_count = scratch1;
+ Register return_pc = scratch2;
+
+ // Get the arguments + receiver count.
+ __ movp(args_count,
+ Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp));
+ __ movl(args_count,
+ FieldOperand(args_count, BytecodeArray::kParameterSizeOffset));
+
+ // Leave the frame (also dropping the register file).
+ __ leave();
+
+ // Drop receiver + arguments.
+ __ PopReturnAddressTo(return_pc);
+ __ addp(rsp, args_count);
+ __ PushReturnAddressFrom(return_pc);
}
// Generate code for entering a JS function with the interpreter.
@@ -702,18 +737,7 @@
masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
// The return value is in rax.
-
- // Get the arguments + reciever count.
- __ movp(rbx, Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp));
- __ movl(rbx, FieldOperand(rbx, BytecodeArray::kParameterSizeOffset));
-
- // Leave the frame (also dropping the register file).
- __ leave();
-
- // Drop receiver + arguments and return.
- __ PopReturnAddressTo(rcx);
- __ addp(rsp, rbx);
- __ PushReturnAddressFrom(rcx);
+ LeaveInterpreterFrame(masm, rbx, rcx);
__ ret(0);
// Load debug copy of the bytecode array.
@@ -737,6 +761,31 @@
__ jmp(rcx);
}
+void Builtins::Generate_InterpreterMarkBaselineOnReturn(MacroAssembler* masm) {
+ // Save the function and context for call to CompileBaseline.
+ __ movp(rdi, Operand(rbp, StandardFrameConstants::kFunctionOffset));
+ __ movp(kContextRegister,
+ Operand(rbp, StandardFrameConstants::kContextOffset));
+
+ // Leave the frame before recompiling for baseline so that we don't count as
+ // an activation on the stack.
+ LeaveInterpreterFrame(masm, rbx, rcx);
+
+ {
+ FrameScope frame_scope(masm, StackFrame::INTERNAL);
+ // Push return value.
+ __ Push(rax);
+
+ // Push function as argument and compile for baseline.
+ __ Push(rdi);
+ __ CallRuntime(Runtime::kCompileBaseline);
+
+ // Restore return value.
+ __ Pop(rax);
+ }
+ __ ret(0);
+}
+
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
bool push_receiver) {
// ----------- S t a t e -------------
@@ -904,13 +953,30 @@
const int bailout_id = BailoutId::None().ToInt();
__ cmpl(temp, Immediate(bailout_id));
__ j(not_equal, &loop_bottom);
+
// Literals available?
+ Label got_literals, maybe_cleared_weakcell;
__ movp(temp, FieldOperand(map, index, times_pointer_size,
SharedFunctionInfo::kOffsetToPreviousLiterals));
+ // temp contains either a WeakCell pointing to the literals array or the
+ // literals array directly.
+ STATIC_ASSERT(WeakCell::kValueOffset == FixedArray::kLengthOffset);
+ __ movp(r15, FieldOperand(temp, WeakCell::kValueOffset));
+ __ JumpIfSmi(r15, &maybe_cleared_weakcell);
+ // r15 is a pointer, therefore temp is a WeakCell pointing to a literals
+ // array.
__ movp(temp, FieldOperand(temp, WeakCell::kValueOffset));
- __ JumpIfSmi(temp, &gotta_call_runtime);
+ __ jmp(&got_literals);
+
+ // r15 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);
+ __ cmpp(r15, Immediate(0));
+ __ j(equal, &gotta_call_runtime);
// Save the literals in the closure.
+ __ bind(&got_literals);
__ movp(FieldOperand(closure, JSFunction::kLiteralsOffset), temp);
__ movp(r15, index);
__ RecordWriteField(closure, JSFunction::kLiteralsOffset, temp, r15,
@@ -1169,6 +1235,9 @@
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
// ----------- S t a t e -------------
+ // -- rax : number of arguments
+ // -- rdi : function
+ // -- rsi : context
// -- rsp[0] : return address
// -- rsp[8] : receiver
// -----------------------------------
@@ -1210,7 +1279,11 @@
__ bind(&receiver_not_date);
{
FrameScope scope(masm, StackFrame::MANUAL);
- __ EnterFrame(StackFrame::INTERNAL);
+ __ Push(rbp);
+ __ Move(rbp, rsp);
+ __ Push(rsi);
+ __ Push(rdi);
+ __ Push(Immediate(0));
__ CallRuntime(Runtime::kThrowNotDateError);
}
}
@@ -1561,6 +1634,8 @@
void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
// ----------- S t a t e -------------
// -- rax : number of arguments
+ // -- rdi : function
+ // -- rsi : context
// -- rsp[0] : return address
// -- rsp[(argc - n) * 8] : arg[n] (zero-based)
// -- rsp[(argc + 1) * 8] : receiver
@@ -1588,27 +1663,32 @@
__ movp(rbx, Operand(rsp, rcx, times_pointer_size, 0));
// Load the double value of the parameter into xmm1, 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(rbx, &convert_smi);
__ JumpIfRoot(FieldOperand(rbx, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex, &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(rbp);
+ __ Move(rbp, rsp);
+ __ Push(rsi);
+ __ Push(rdi);
__ Integer32ToSmi(rax, rax);
__ Integer32ToSmi(rcx, rcx);
__ Push(rax);
__ Push(rcx);
__ Push(rdx);
__ movp(rax, rbx);
- ToNumberStub stub(masm->isolate());
- __ CallStub(&stub);
+ __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ movp(rbx, rax);
__ Pop(rdx);
__ Pop(rcx);
__ Pop(rax);
+ __ Pop(rdi);
+ __ Pop(rsi);
{
// Restore the double accumulator value (xmm0).
Label restore_smi, done_restore;
@@ -1621,6 +1701,7 @@
}
__ SmiToInteger32(rcx, rcx);
__ SmiToInteger32(rax, rax);
+ __ leave();
}
__ jmp(&convert);
__ bind(&convert_number);
@@ -1694,8 +1775,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 (already in rax).
__ bind(&no_arguments);
@@ -1746,8 +1826,7 @@
__ Push(rdx);
__ Push(rdi);
__ Move(rax, rbx);
- ToNumberStub stub(masm->isolate());
- __ CallStub(&stub);
+ __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ Move(rbx, rax);
__ Pop(rdi);
__ Pop(rdx);
@@ -2001,6 +2080,81 @@
__ TailCallRuntime(Runtime::kAllocateInTargetSpace);
}
+void Builtins::Generate_StringToNumber(MacroAssembler* masm) {
+ // The StringToNumber stub takes one argument in rax.
+ __ AssertString(rax);
+
+ // Check if string has a cached array index.
+ Label runtime;
+ __ testl(FieldOperand(rax, String::kHashFieldOffset),
+ Immediate(String::kContainsCachedArrayIndexMask));
+ __ j(not_zero, &runtime, Label::kNear);
+ __ movl(rax, FieldOperand(rax, String::kHashFieldOffset));
+ __ IndexFromHash(rax, rax);
+ __ Ret();
+
+ __ bind(&runtime);
+ {
+ FrameScope frame(masm, StackFrame::INTERNAL);
+ // Push argument.
+ __ Push(rax);
+ // 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 rax.
+ Label not_smi;
+ __ JumpIfNotSmi(rax, ¬_smi, Label::kNear);
+ __ Ret();
+ __ bind(¬_smi);
+
+ Label not_heap_number;
+ __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
+ Heap::kHeapNumberMapRootIndex);
+ __ j(not_equal, ¬_heap_number, Label::kNear);
+ __ 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 rax.
+ __ AssertNotNumber(rax);
+
+ Label not_string;
+ __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdi);
+ // rax: object
+ // rdi: object map
+ __ j(above_equal, ¬_string, Label::kNear);
+ __ Jump(masm->isolate()->builtins()->StringToNumber(),
+ RelocInfo::CODE_TARGET);
+ __ bind(¬_string);
+
+ Label not_oddball;
+ __ CmpInstanceType(rdi, ODDBALL_TYPE);
+ __ j(not_equal, ¬_oddball, Label::kNear);
+ __ movp(rax, FieldOperand(rax, Oddball::kToNumberOffset));
+ __ Ret();
+ __ bind(¬_oddball);
+ {
+ FrameScope frame(masm, StackFrame::INTERNAL);
+ // Push argument.
+ __ Push(rax);
+ // 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 -------------
// -- rax : actual number of arguments