summaryrefslogtreecommitdiff
path: root/deps/v8/src/builtins/x87/builtins-x87.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/builtins/x87/builtins-x87.cc')
-rw-r--r--deps/v8/src/builtins/x87/builtins-x87.cc168
1 files changed, 75 insertions, 93 deletions
diff --git a/deps/v8/src/builtins/x87/builtins-x87.cc b/deps/v8/src/builtins/x87/builtins-x87.cc
index 2187f86f61..9071beb59d 100644
--- a/deps/v8/src/builtins/x87/builtins-x87.cc
+++ b/deps/v8/src/builtins/x87/builtins-x87.cc
@@ -135,8 +135,8 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function,
// Allocate the new receiver object.
__ Push(edi);
__ Push(edx);
- FastNewObjectStub stub(masm->isolate());
- __ CallStub(&stub);
+ __ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
+ RelocInfo::CODE_TARGET);
__ mov(ebx, eax);
__ Pop(edx);
__ Pop(edi);
@@ -387,17 +387,16 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ mov(FieldOperand(ebx, JSGeneratorObject::kResumeModeOffset), edx);
// Load suspended function and context.
- __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset));
__ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
+ __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
// Flood function if we are stepping.
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);
+ ExternalReference debug_hook =
+ ExternalReference::debug_hook_on_function_call_address(masm->isolate());
+ __ cmpb(Operand::StaticVariable(debug_hook), Immediate(0));
+ __ j(not_equal, &prepare_step_in_if_stepping);
// Flood function if we need to continue stepping in the suspended generator.
ExternalReference debug_suspended_generator =
@@ -438,19 +437,20 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ bind(&done_loop);
}
- // Dispatch on the kind of generator object.
- Label old_generator;
- __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
- __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kFunctionDataOffset));
- __ CmpObjectType(ecx, BYTECODE_ARRAY_TYPE, ecx);
- __ j(not_equal, &old_generator);
+ // Underlying function needs to have bytecode available.
+ if (FLAG_debug_code) {
+ __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
+ __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kFunctionDataOffset));
+ __ CmpObjectType(ecx, BYTECODE_ARRAY_TYPE, ecx);
+ __ Assert(equal, kMissingBytecodeArray);
+ }
- // New-style (ignition/turbofan) generator object
+ // Resume (Ignition/TurboFan) generator object.
{
__ PushReturnAddressFrom(eax);
__ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ mov(eax,
- FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset));
+ FieldOperand(eax, SharedFunctionInfo::kFormalParameterCountOffset));
// 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.
@@ -458,56 +458,13 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
__ jmp(FieldOperand(edi, JSFunction::kCodeEntryOffset));
}
- // Old-style (full-codegen) generator object
- __ bind(&old_generator);
- {
- // Enter a new JavaScript frame, and initialize its slots as they were when
- // the generator was suspended.
- FrameScope scope(masm, StackFrame::MANUAL);
- __ PushReturnAddressFrom(eax); // Return address.
- __ Push(ebp); // Caller's frame pointer.
- __ Move(ebp, esp);
- __ Push(esi); // Callee's context.
- __ Push(edi); // Callee's JS Function.
-
- // Restore the operand stack.
- __ mov(eax, FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset));
- {
- Label done_loop, loop;
- __ Move(ecx, Smi::kZero);
- __ bind(&loop);
- __ cmp(ecx, FieldOperand(eax, FixedArray::kLengthOffset));
- __ j(equal, &done_loop, Label::kNear);
- __ Push(FieldOperand(eax, ecx, times_half_pointer_size,
- FixedArray::kHeaderSize));
- __ add(ecx, Immediate(Smi::FromInt(1)));
- __ jmp(&loop);
- __ bind(&done_loop);
- }
-
- // Reset operand stack so we don't leak.
- __ mov(FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset),
- Immediate(masm->isolate()->factory()->empty_fixed_array()));
-
- // Resume the generator function at the continuation.
- __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
- __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
- __ mov(ecx, FieldOperand(ebx, JSGeneratorObject::kContinuationOffset));
- __ SmiUntag(ecx);
- __ lea(edx, FieldOperand(edx, ecx, times_1, Code::kHeaderSize));
- __ mov(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset),
- Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)));
- __ 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);
+ __ CallRuntime(Runtime::kDebugOnFunctionCall);
__ Pop(edx);
__ Pop(ebx);
__ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
@@ -606,6 +563,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
}
+ // Reset code age.
+ __ mov_b(FieldOperand(kInterpreterBytecodeArrayRegister,
+ BytecodeArray::kBytecodeAgeOffset),
+ Immediate(BytecodeArray::kNoAgeBytecodeAge));
+
// Push bytecode array.
__ push(kInterpreterBytecodeArrayRegister);
// Push Smi tagged initial bytecode array offset.
@@ -1093,12 +1055,6 @@ void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
__ mov(temp, FieldOperand(temp, WeakCell::kValueOffset));
__ cmp(temp, native_context);
__ j(not_equal, &loop_bottom);
- // OSR id set to none?
- __ mov(temp, FieldOperand(map, index, times_half_pointer_size,
- SharedFunctionInfo::kOffsetToPreviousOsrAstId));
- const int bailout_id = BailoutId::None().ToInt();
- __ cmp(temp, Immediate(Smi::FromInt(bailout_id)));
- __ j(not_equal, &loop_bottom);
// Literals available?
__ mov(temp, FieldOperand(map, index, times_half_pointer_size,
SharedFunctionInfo::kOffsetToPreviousLiterals));
@@ -1166,14 +1122,14 @@ void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
__ test_b(FieldOperand(entry, SharedFunctionInfo::kMarkedForTierUpByteOffset),
Immediate(1 << SharedFunctionInfo::kMarkedForTierUpBitWithinByte));
__ j(not_zero, &gotta_call_runtime_no_stack);
- // Is the full code valid?
+
+ // If SFI points to anything other than CompileLazy, install that.
__ mov(entry, FieldOperand(entry, SharedFunctionInfo::kCodeOffset));
- __ mov(ebx, FieldOperand(entry, Code::kFlagsOffset));
- __ and_(ebx, Code::KindField::kMask);
- __ shr(ebx, Code::KindField::kShift);
- __ cmp(ebx, Immediate(Code::BUILTIN));
+ __ Move(ebx, masm->CodeObject());
+ __ cmp(entry, ebx);
__ j(equal, &gotta_call_runtime_no_stack);
- // Yes, install the full code.
+
+ // Install the SFI's code entry.
__ lea(entry, FieldOperand(entry, Code::kHeaderSize));
__ mov(FieldOperand(closure, JSFunction::kCodeEntryOffset), entry);
__ RecordWriteCodeEntryField(closure, entry, ebx);
@@ -1295,14 +1251,9 @@ static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
__ ret(0);
}
-#define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \
- void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \
- MacroAssembler* masm) { \
- GenerateMakeCodeYoungAgainCommon(masm); \
- } \
- void Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \
- MacroAssembler* masm) { \
- GenerateMakeCodeYoungAgainCommon(masm); \
+#define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \
+ void Builtins::Generate_Make##C##CodeYoungAgain(MacroAssembler* masm) { \
+ GenerateMakeCodeYoungAgainCommon(masm); \
}
CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR)
#undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
@@ -1986,8 +1937,8 @@ void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
FrameScope scope(masm, StackFrame::MANUAL);
__ EnterBuiltinFrame(esi, edi, ecx);
__ Push(ebx); // the first argument
- FastNewObjectStub stub(masm->isolate());
- __ CallStub(&stub);
+ __ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
+ RelocInfo::CODE_TARGET);
__ Pop(FieldOperand(eax, JSValue::kValueOffset));
__ LeaveBuiltinFrame(esi, edi, ecx);
}
@@ -2149,8 +2100,8 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
__ SmiTag(ebx);
__ EnterBuiltinFrame(esi, edi, ebx);
__ Push(eax); // the first argument
- FastNewObjectStub stub(masm->isolate());
- __ CallStub(&stub);
+ __ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
+ RelocInfo::CODE_TARGET);
__ Pop(FieldOperand(eax, JSValue::kValueOffset));
__ LeaveBuiltinFrame(esi, edi, ebx);
__ SmiUntag(ebx);
@@ -2210,7 +2161,8 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
// Create the list of arguments from the array-like argumentsList.
{
- Label create_arguments, create_array, create_runtime, done_create;
+ Label create_arguments, create_array, create_holey_array, create_runtime,
+ done_create;
__ JumpIfSmi(eax, &create_runtime);
// Load the map of argumentsList into ecx.
@@ -2254,6 +2206,22 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
__ mov(eax, ecx);
__ jmp(&done_create);
+ // For holey JSArrays we need to check that the array prototype chain
+ // protector is intact and our prototype is the Array.prototype actually.
+ __ bind(&create_holey_array);
+ __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
+ __ mov(ecx, FieldOperand(ecx, Map::kPrototypeOffset));
+ __ cmp(ecx, ContextOperand(ebx, Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
+ __ j(not_equal, &create_runtime);
+ __ LoadRoot(ecx, Heap::kArrayProtectorRootIndex);
+ __ cmp(FieldOperand(ecx, PropertyCell::kValueOffset),
+ Immediate(Smi::FromInt(Isolate::kProtectorValid)));
+ __ j(not_equal, &create_runtime);
+ __ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset));
+ __ SmiUntag(ebx);
+ __ mov(eax, FieldOperand(eax, JSArray::kElementsOffset));
+ __ jmp(&done_create);
+
// Try to create the list from a JSArray object.
__ bind(&create_array);
__ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset));
@@ -2261,10 +2229,12 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
STATIC_ASSERT(FAST_ELEMENTS == 2);
- __ cmp(ecx, Immediate(FAST_ELEMENTS));
- __ j(above, &create_runtime);
+ STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
__ cmp(ecx, Immediate(FAST_HOLEY_SMI_ELEMENTS));
- __ j(equal, &create_runtime);
+ __ j(equal, &create_holey_array, Label::kNear);
+ __ cmp(ecx, Immediate(FAST_HOLEY_ELEMENTS));
+ __ j(equal, &create_holey_array, Label::kNear);
+ __ j(above, &create_runtime);
__ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset));
__ SmiUntag(ebx);
__ mov(eax, FieldOperand(eax, JSArray::kElementsOffset));
@@ -2303,26 +2273,38 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
// Push arguments onto the stack (thisArgument is already on the stack).
{
+ // Save edx/edi to stX0/stX1.
__ push(edx);
+ __ push(edi);
__ fld_s(MemOperand(esp, 0));
- __ lea(esp, Operand(esp, kFloatSize));
+ __ fld_s(MemOperand(esp, 4));
+ __ lea(esp, Operand(esp, 2 * kFloatSize));
__ PopReturnAddressTo(edx);
__ Move(ecx, Immediate(0));
- Label done, loop;
+ Label done, push, loop;
__ bind(&loop);
__ cmp(ecx, ebx);
__ j(equal, &done, Label::kNear);
- __ Push(
- FieldOperand(eax, ecx, times_pointer_size, FixedArray::kHeaderSize));
+ // Turn the hole into undefined as we go.
+ __ mov(edi,
+ FieldOperand(eax, ecx, times_pointer_size, FixedArray::kHeaderSize));
+ __ CompareRoot(edi, Heap::kTheHoleValueRootIndex);
+ __ j(not_equal, &push, Label::kNear);
+ __ LoadRoot(edi, Heap::kUndefinedValueRootIndex);
+ __ bind(&push);
+ __ Push(edi);
__ inc(ecx);
__ jmp(&loop);
__ bind(&done);
__ PushReturnAddressFrom(edx);
- __ lea(esp, Operand(esp, -kFloatSize));
+ // Restore edx/edi from stX0/stX1.
+ __ lea(esp, Operand(esp, -2 * kFloatSize));
__ fstp_s(MemOperand(esp, 0));
+ __ fstp_s(MemOperand(esp, 4));
__ pop(edx);
+ __ pop(edi);
__ Move(eax, ebx);
}