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/x87/builtins-x87.cc b/src/x87/builtins-x87.cc
index 7018802..0600f0d 100644
--- a/src/x87/builtins-x87.cc
+++ b/src/x87/builtins-x87.cc
@@ -16,10 +16,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 -------------
// -- eax : number of arguments excluding receiver
// -- edi : target
@@ -39,19 +36,11 @@
__ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
// Insert extra arguments.
- int num_extra_args = 0;
- if (extra_args != BuiltinExtraArguments::kNone) {
- __ PopReturnAddressTo(ecx);
- if (extra_args & BuiltinExtraArguments::kTarget) {
- ++num_extra_args;
- __ Push(edi);
- }
- if (extra_args & BuiltinExtraArguments::kNewTarget) {
- ++num_extra_args;
- __ Push(edx);
- }
- __ PushReturnAddressFrom(ecx);
- }
+ const int num_extra_args = 2;
+ __ PopReturnAddressTo(ecx);
+ __ Push(edi);
+ __ Push(edx);
+ __ PushReturnAddressFrom(ecx);
// JumpToExternalReference expects eax to contain the number of arguments
// including the receiver and the extra arguments.
@@ -396,8 +385,8 @@
__ AssertGeneratorObject(ebx);
// Store input value into generator object.
- __ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), eax);
- __ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, eax, ecx,
+ __ mov(FieldOperand(ebx, JSGeneratorObject::kInputOrDebugPosOffset), eax);
+ __ RecordWriteField(ebx, JSGeneratorObject::kInputOrDebugPosOffset, eax, ecx,
kDontSaveFPRegs);
// Store resume mode into generator object.
@@ -408,22 +397,20 @@
__ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
// Flood function if we are stepping.
- Label skip_flooding;
- ExternalReference step_in_enabled =
- ExternalReference::debug_step_in_enabled_address(masm->isolate());
- __ cmpb(Operand::StaticVariable(step_in_enabled), Immediate(0));
- __ j(equal, &skip_flooding);
- {
- FrameScope scope(masm, StackFrame::INTERNAL);
- __ Push(ebx);
- __ Push(edx);
- __ Push(edi);
- __ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
- __ Pop(edx);
- __ Pop(ebx);
- __ mov(edi, FieldOperand(ebx, 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);
+ __ cmpb(Operand::StaticVariable(last_step_action), 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());
+ __ cmp(ebx, Operand::StaticVariable(debug_suspended_generator));
+ __ j(equal, &prepare_step_in_suspended_generator);
+ __ bind(&stepping_prepared);
// Pop return address.
__ PopReturnAddressTo(eax);
@@ -519,6 +506,51 @@
__ mov(eax, ebx); // Continuation expects generator object in eax.
__ jmp(edx);
}
+
+ __ bind(&prepare_step_in_if_stepping);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(ebx);
+ __ Push(edx);
+ __ Push(edi);
+ __ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
+ __ Pop(edx);
+ __ Pop(ebx);
+ __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
+ }
+ __ jmp(&stepping_prepared);
+
+ __ bind(&prepare_step_in_suspended_generator);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Push(ebx);
+ __ Push(edx);
+ __ CallRuntime(Runtime::kDebugPrepareStepInSuspendedGenerator);
+ __ Pop(edx);
+ __ Pop(ebx);
+ __ mov(edi, FieldOperand(ebx, 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 + reciever count.
+ __ mov(args_count,
+ Operand(ebp, InterpreterFrameConstants::kBytecodeArrayFromFp));
+ __ mov(args_count,
+ FieldOperand(args_count, BytecodeArray::kParameterSizeOffset));
+
+ // Leave the frame (also dropping the register file).
+ __ leave();
+
+ // Drop receiver + arguments.
+ __ pop(return_pc);
+ __ add(esp, args_count);
+ __ push(return_pc);
}
// Generate code for entering a JS function with the interpreter.
@@ -624,18 +656,7 @@
masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
// The return value is in eax.
-
- // Get the arguments + reciever count.
- __ mov(ebx, Operand(ebp, InterpreterFrameConstants::kBytecodeArrayFromFp));
- __ mov(ebx, FieldOperand(ebx, BytecodeArray::kParameterSizeOffset));
-
- // Leave the frame (also dropping the register file).
- __ leave();
-
- // Drop receiver + arguments and return.
- __ pop(ecx);
- __ add(esp, ebx);
- __ push(ecx);
+ LeaveInterpreterFrame(masm, ebx, ecx);
__ ret(0);
// Load debug copy of the bytecode array.
@@ -662,6 +683,31 @@
__ jmp(ecx);
}
+void Builtins::Generate_InterpreterMarkBaselineOnReturn(MacroAssembler* masm) {
+ // Save the function and context for call to CompileBaseline.
+ __ mov(edi, Operand(ebp, StandardFrameConstants::kFunctionOffset));
+ __ mov(kContextRegister,
+ Operand(ebp, StandardFrameConstants::kContextOffset));
+
+ // Leave the frame before recompiling for baseline so that we don't count as
+ // an activation on the stack.
+ LeaveInterpreterFrame(masm, ebx, ecx);
+
+ {
+ FrameScope frame_scope(masm, StackFrame::INTERNAL);
+ // Push return value.
+ __ push(eax);
+
+ // Push function as argument and compile for baseline.
+ __ push(edi);
+ __ CallRuntime(Runtime::kCompileBaseline);
+
+ // Restore return value.
+ __ pop(eax);
+ }
+ __ ret(0);
+}
+
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
Register array_limit) {
// ----------- S t a t e -------------
@@ -841,13 +887,30 @@
const int bailout_id = BailoutId::None().ToInt();
__ cmp(temp, Immediate(Smi::FromInt(bailout_id)));
__ j(not_equal, &loop_bottom);
+
// Literals available?
+ Label got_literals, maybe_cleared_weakcell;
__ mov(temp, FieldOperand(map, index, times_half_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);
+ __ JumpIfSmi(FieldOperand(temp, WeakCell::kValueOffset),
+ &maybe_cleared_weakcell);
+ // The WeakCell value is a pointer, therefore it's a valid literals array.
__ mov(temp, FieldOperand(temp, WeakCell::kValueOffset));
- __ JumpIfSmi(temp, &gotta_call_runtime);
+ __ jmp(&got_literals);
+
+ // We have 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(FieldOperand(temp, WeakCell::kValueOffset), Immediate(0));
+ __ j(equal, &gotta_call_runtime);
// Save the literals in the closure.
+ __ bind(&got_literals);
__ mov(ecx, Operand(esp, 0));
__ mov(FieldOperand(ecx, JSFunction::kLiteralsOffset), temp);
__ push(index);
@@ -1120,6 +1183,9 @@
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
// ----------- S t a t e -------------
+ // -- eax : number of arguments
+ // -- edi : function
+ // -- esi : context
// -- esp[0] : return address
// -- esp[4] : receiver
// -----------------------------------
@@ -1162,7 +1228,11 @@
__ bind(&receiver_not_date);
{
FrameScope scope(masm, StackFrame::MANUAL);
- __ EnterFrame(StackFrame::INTERNAL);
+ __ Push(ebp);
+ __ Move(ebp, esp);
+ __ Push(esi);
+ __ Push(edi);
+ __ Push(Immediate(0));
__ CallRuntime(Runtime::kThrowNotDateError);
}
}
@@ -1496,6 +1566,8 @@
void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
// ----------- S t a t e -------------
// -- eax : number of arguments
+ // -- edi : function
+ // -- esi : context
// -- esp[0] : return address
// -- esp[(argc - n) * 8] : arg[n] (zero-based)
// -- esp[(argc + 1) * 8] : receiver
@@ -1523,27 +1595,32 @@
__ mov(ebx, Operand(esp, ecx, times_pointer_size, 0));
// Load the double value of the parameter into stx_1, 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(ebx, &convert_smi);
__ JumpIfRoot(FieldOperand(ebx, 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(ebp);
+ __ Move(ebp, esp);
+ __ Push(esi);
+ __ Push(edi);
__ SmiTag(eax);
__ SmiTag(ecx);
__ Push(eax);
__ Push(ecx);
__ Push(edx);
__ mov(eax, ebx);
- ToNumberStub stub(masm->isolate());
- __ CallStub(&stub);
+ __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ mov(ebx, eax);
__ Pop(edx);
__ Pop(ecx);
__ Pop(eax);
+ __ Pop(edi);
+ __ Pop(esi);
{
// Restore the double accumulator value (stX_0).
Label restore_smi, done_restore;
@@ -1560,6 +1637,7 @@
}
__ SmiUntag(ecx);
__ SmiUntag(eax);
+ __ leave();
}
__ jmp(&convert);
__ bind(&convert_number);
@@ -1650,8 +1728,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 eax).
__ bind(&no_arguments);
@@ -1701,8 +1778,7 @@
__ Push(edi);
__ Push(edx);
__ Move(eax, ebx);
- ToNumberStub stub(masm->isolate());
- __ CallStub(&stub);
+ __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ Move(ebx, eax);
__ Pop(edx);
__ Pop(edi);
@@ -2601,6 +2677,81 @@
__ TailCallRuntime(Runtime::kAllocateInTargetSpace);
}
+// static
+void Builtins::Generate_StringToNumber(MacroAssembler* masm) {
+ // The StringToNumber stub takes one argument in eax.
+ __ AssertString(eax);
+
+ // Check if string has a cached array index.
+ Label runtime;
+ __ test(FieldOperand(eax, String::kHashFieldOffset),
+ Immediate(String::kContainsCachedArrayIndexMask));
+ __ j(not_zero, &runtime, Label::kNear);
+ __ mov(eax, FieldOperand(eax, String::kHashFieldOffset));
+ __ IndexFromHash(eax, eax);
+ __ Ret();
+
+ __ bind(&runtime);
+ {
+ FrameScope frame(masm, StackFrame::INTERNAL);
+ // Push argument.
+ __ push(eax);
+ // 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 eax.
+ Label not_smi;
+ __ JumpIfNotSmi(eax, ¬_smi, Label::kNear);
+ __ Ret();
+ __ bind(¬_smi);
+
+ Label not_heap_number;
+ __ CompareMap(eax, masm->isolate()->factory()->heap_number_map());
+ __ 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 eax.
+ __ AssertNotNumber(eax);
+
+ Label not_string;
+ __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edi);
+ // eax: object
+ // edi: object map
+ __ j(above_equal, ¬_string, Label::kNear);
+ __ Jump(masm->isolate()->builtins()->StringToNumber(),
+ RelocInfo::CODE_TARGET);
+ __ bind(¬_string);
+
+ Label not_oddball;
+ __ CmpInstanceType(edi, ODDBALL_TYPE);
+ __ j(not_equal, ¬_oddball, Label::kNear);
+ __ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset));
+ __ Ret();
+ __ bind(¬_oddball);
+ {
+ FrameScope frame(masm, StackFrame::INTERNAL);
+ // Push argument.
+ __ push(eax);
+ // 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 -------------
// -- eax : actual number of arguments