summaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/ia32/builtins-ia32.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/builtins/ia32/builtins-ia32.cc')
-rw-r--r--deps/v8/src/builtins/ia32/builtins-ia32.cc158
1 files changed, 63 insertions, 95 deletions
diff --git a/deps/v8/src/builtins/ia32/builtins-ia32.cc b/deps/v8/src/builtins/ia32/builtins-ia32.cc
index a689c3131d..7635bada49 100644
--- a/deps/v8/src/builtins/ia32/builtins-ia32.cc
+++ b/deps/v8/src/builtins/ia32/builtins-ia32.cc
@@ -5,7 +5,6 @@
#if V8_TARGET_ARCH_IA32
#include "src/code-factory.h"
-#include "src/codegen.h"
#include "src/debug/debug.h"
#include "src/deoptimizer.h"
#include "src/frame-constants.h"
@@ -55,12 +54,12 @@ void AdaptorWithExitFrameType(MacroAssembler* masm,
// CEntryStub expects eax to contain the number of arguments including the
// receiver and the extra arguments.
- const int num_extra_args = 3;
- __ add(eax, Immediate(num_extra_args + 1));
+ __ add(eax, Immediate(BuiltinExitFrameConstants::kNumExtraArgsWithReceiver));
// Insert extra arguments.
__ PopReturnAddressTo(ecx);
__ SmiTag(eax);
+ __ PushRoot(Heap::kTheHoleValueRootIndex); // Padding.
__ Push(eax);
__ SmiUntag(eax);
__ Push(edi);
@@ -396,37 +395,30 @@ void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
__ CallRuntime(Runtime::kThrowConstructedNonConstructable);
}
-enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt };
-
-// Clobbers ecx, edx, edi; preserves all other registers.
-static void Generate_CheckStackOverflow(MacroAssembler* masm,
- IsTagged eax_is_tagged) {
- // eax : the number of items to be pushed to the stack
- //
+static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
+ Register scratch1, Register scratch2,
+ Label* stack_overflow,
+ bool include_receiver = false) {
// Check the stack for overflow. We are not trying to catch
// interruptions (e.g. debug break and preemption) here, so the "real stack
// limit" is checked.
- Label okay;
ExternalReference real_stack_limit =
ExternalReference::address_of_real_stack_limit(masm->isolate());
- __ mov(edi, Operand::StaticVariable(real_stack_limit));
- // Make ecx the space we have left. The stack might already be overflowed
- // here which will cause ecx to become negative.
- __ mov(ecx, esp);
- __ sub(ecx, edi);
- // Make edx the space we need for the array when it is unrolled onto the
+ __ mov(scratch1, Operand::StaticVariable(real_stack_limit));
+ // Make scratch2 the space we have left. The stack might already be overflowed
+ // here which will cause scratch2 to become negative.
+ __ mov(scratch2, esp);
+ __ sub(scratch2, scratch1);
+ // Make scratch1 the space we need for the array when it is unrolled onto the
// stack.
- __ mov(edx, eax);
- int smi_tag = eax_is_tagged == kEaxIsSmiTagged ? kSmiTagSize : 0;
- __ shl(edx, kPointerSizeLog2 - smi_tag);
+ __ mov(scratch1, num_args);
+ if (include_receiver) {
+ __ add(scratch1, Immediate(1));
+ }
+ __ shl(scratch1, kPointerSizeLog2);
// Check if the arguments will overflow the stack.
- __ cmp(ecx, edx);
- __ j(greater, &okay); // Signed comparison.
-
- // Out of stack space.
- __ CallRuntime(Runtime::kThrowStackOverflow);
-
- __ bind(&okay);
+ __ cmp(scratch2, scratch1);
+ __ j(less_equal, stack_overflow); // Signed comparison.
}
static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
@@ -453,8 +445,17 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
__ mov(ebx, Operand(ebx, EntryFrameConstants::kArgvOffset));
// Check if we have enough stack space to push all arguments.
- // Expects argument count in eax. Clobbers ecx, edx, edi.
- Generate_CheckStackOverflow(masm, kEaxIsUntaggedInt);
+ // Argument count in eax. Clobbers ecx and edx.
+ Label enough_stack_space, stack_overflow;
+ Generate_StackOverflowCheck(masm, eax, ecx, edx, &stack_overflow);
+ __ jmp(&enough_stack_space);
+
+ __ bind(&stack_overflow);
+ __ CallRuntime(Runtime::kThrowStackOverflow);
+ // This should be unreachable.
+ __ int3();
+
+ __ bind(&enough_stack_space);
// Copy arguments to the stack in a loop.
Label loop, entry;
@@ -500,22 +501,18 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : the value to pass to the generator
- // -- ebx : the JSGeneratorObject to resume
- // -- edx : the resume mode (tagged)
+ // -- edx : the JSGeneratorObject to resume
// -- esp[0] : return address
// -----------------------------------
- __ AssertGeneratorObject(ebx);
+ __ AssertGeneratorObject(edx);
// Store input value into generator object.
- __ mov(FieldOperand(ebx, JSGeneratorObject::kInputOrDebugPosOffset), eax);
- __ RecordWriteField(ebx, JSGeneratorObject::kInputOrDebugPosOffset, eax, ecx,
+ __ mov(FieldOperand(edx, JSGeneratorObject::kInputOrDebugPosOffset), eax);
+ __ RecordWriteField(edx, JSGeneratorObject::kInputOrDebugPosOffset, eax, ecx,
kDontSaveFPRegs);
- // Store resume mode into generator object.
- __ mov(FieldOperand(ebx, JSGeneratorObject::kResumeModeOffset), edx);
-
// Load suspended function and context.
- __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
+ __ mov(edi, FieldOperand(edx, JSGeneratorObject::kFunctionOffset));
__ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
// Flood function if we are stepping.
@@ -529,20 +526,25 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
// 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));
+ __ cmp(edx, Operand::StaticVariable(debug_suspended_generator));
__ j(equal, &prepare_step_in_suspended_generator);
__ bind(&stepping_prepared);
+ // Check the stack for overflow. We are not trying to catch interruptions
+ // (i.e. debug break and preemption) here, so check the "real stack limit".
+ Label stack_overflow;
+ __ CompareRoot(esp, ecx, Heap::kRealStackLimitRootIndex);
+ __ j(below, &stack_overflow);
+
// Pop return address.
__ PopReturnAddressTo(eax);
// Push receiver.
- __ Push(FieldOperand(ebx, JSGeneratorObject::kReceiverOffset));
+ __ Push(FieldOperand(edx, JSGeneratorObject::kReceiverOffset));
// ----------- S t a t e -------------
// -- eax : return address
- // -- ebx : the JSGeneratorObject to resume
- // -- edx : the resume mode (tagged)
+ // -- edx : the JSGeneratorObject to resume
// -- edi : generator function
// -- esi : generator context
// -- esp[0] : generator receiver
@@ -582,7 +584,6 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
// 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.
- __ mov(edx, ebx);
__ mov(ecx, FieldOperand(edi, JSFunction::kCodeOffset));
__ add(ecx, Immediate(Code::kHeaderSize - kHeapObjectTag));
__ jmp(ecx);
@@ -591,27 +592,30 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ bind(&prepare_step_in_if_stepping);
{
FrameScope scope(masm, StackFrame::INTERNAL);
- __ Push(ebx);
__ Push(edx);
__ Push(edi);
__ CallRuntime(Runtime::kDebugOnFunctionCall);
__ Pop(edx);
- __ Pop(ebx);
- __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
+ __ mov(edi, FieldOperand(edx, 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));
+ __ mov(edi, FieldOperand(edx, JSGeneratorObject::kFunctionOffset));
}
__ jmp(&stepping_prepared);
+
+ __ bind(&stack_overflow);
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ CallRuntime(Runtime::kThrowStackOverflow);
+ __ int3(); // This should be unreachable.
+ }
}
static void ReplaceClosureCodeWithOptimizedCode(
@@ -717,18 +721,20 @@ static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm,
__ mov(optimized_code_entry,
FieldOperand(optimized_code_entry, WeakCell::kValueOffset));
__ JumpIfSmi(optimized_code_entry, &fallthrough);
+ __ push(eax);
+ __ push(edx);
// Check if the optimized code is marked for deopt. If it is, bailout to a
// given label.
Label found_deoptimized_code;
- __ test(FieldOperand(optimized_code_entry, Code::kKindSpecificFlags1Offset),
+ __ mov(eax,
+ FieldOperand(optimized_code_entry, Code::kCodeDataContainerOffset));
+ __ test(FieldOperand(eax, CodeDataContainer::kKindSpecificFlagsOffset),
Immediate(1 << Code::kMarkedForDeoptimizationBit));
__ j(not_zero, &found_deoptimized_code);
// Optimized code is good, get it into the closure and link the closure into
// the optimized functions list, then tail call the optimized code.
- __ push(eax);
- __ push(edx);
// The feedback vector is no longer used, so re-use it as a scratch
// register.
ReplaceClosureCodeWithOptimizedCode(masm, optimized_code_entry, closure,
@@ -741,6 +747,8 @@ static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm,
// Optimized code slot contains deoptimized code, evict it and re-enter the
// closure's code.
__ bind(&found_deoptimized_code);
+ __ pop(edx);
+ __ pop(eax);
GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot);
}
@@ -962,32 +970,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
}
-static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
- Register scratch1, Register scratch2,
- Label* stack_overflow,
- bool include_receiver = false) {
- // Check the stack for overflow. We are not trying to catch
- // interruptions (e.g. debug break and preemption) here, so the "real stack
- // limit" is checked.
- ExternalReference real_stack_limit =
- ExternalReference::address_of_real_stack_limit(masm->isolate());
- __ mov(scratch1, Operand::StaticVariable(real_stack_limit));
- // Make scratch2 the space we have left. The stack might already be overflowed
- // here which will cause scratch2 to become negative.
- __ mov(scratch2, esp);
- __ sub(scratch2, scratch1);
- // Make scratch1 the space we need for the array when it is unrolled onto the
- // stack.
- __ mov(scratch1, num_args);
- if (include_receiver) {
- __ add(scratch1, Immediate(1));
- }
- __ shl(scratch1, kPointerSizeLog2);
- // Check if the arguments will overflow the stack.
- __ cmp(scratch2, scratch1);
- __ j(less_equal, stack_overflow); // Signed comparison.
-}
-
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
Register array_limit,
Register start_address) {
@@ -1542,20 +1524,6 @@ void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
__ jmp(ecx);
}
-void Builtins::Generate_NotifyBuiltinContinuation(MacroAssembler* masm) {
- // Enter an internal frame.
- {
- FrameScope scope(masm, StackFrame::INTERNAL);
- // Preserve possible return result from lazy deopt.
- __ push(eax);
- __ CallRuntime(Runtime::kNotifyStubFailure, false);
- __ pop(eax);
- // Tear down internal frame.
- }
-
- __ Ret(); // Return to ContinueToBuiltin stub still on stack.
-}
-
namespace {
void Generate_ContinueToBuiltinHelper(MacroAssembler* masm,
bool java_script_builtin,
@@ -1848,7 +1816,7 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
if (FLAG_debug_code) {
// Initial map for the builtin InternalArray function should be a map.
__ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
- // Will both indicate a NULL and a Smi.
+ // Will both indicate a nullptr and a Smi.
__ test(ebx, Immediate(kSmiTagMask));
__ Assert(not_zero, kUnexpectedInitialMapForInternalArrayFunction);
__ CmpObjectType(ebx, MAP_TYPE, ecx);
@@ -1877,7 +1845,7 @@ void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
if (FLAG_debug_code) {
// Initial map for the builtin Array function should be a map.
__ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
- // Will both indicate a NULL and a Smi.
+ // Will both indicate a nullptr and a Smi.
__ test(ebx, Immediate(kSmiTagMask));
__ Assert(not_zero, kUnexpectedInitialMapForArrayFunction);
__ CmpObjectType(ebx, MAP_TYPE, ecx);
@@ -2658,7 +2626,7 @@ static void Generate_OnStackReplacementHelper(MacroAssembler* masm,
// Load the OSR entrypoint offset from the deoptimization data.
__ mov(ebx, Operand(ebx, FixedArray::OffsetOfElementAt(
- DeoptimizationInputData::kOsrPcOffsetIndex) -
+ DeoptimizationData::kOsrPcOffsetIndex) -
kHeapObjectTag));
__ SmiUntag(ebx);