diff options
Diffstat (limited to 'deps/v8/src/builtins/ia32/builtins-ia32.cc')
-rw-r--r-- | deps/v8/src/builtins/ia32/builtins-ia32.cc | 160 |
1 files changed, 69 insertions, 91 deletions
diff --git a/deps/v8/src/builtins/ia32/builtins-ia32.cc b/deps/v8/src/builtins/ia32/builtins-ia32.cc index 4287333d3f..2cf1708b12 100644 --- a/deps/v8/src/builtins/ia32/builtins-ia32.cc +++ b/deps/v8/src/builtins/ia32/builtins-ia32.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); @@ -386,17 +386,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 = @@ -437,19 +436,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. @@ -457,56 +457,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)); @@ -605,6 +562,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. @@ -1092,12 +1054,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)); @@ -1165,14 +1121,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); @@ -1294,14 +1250,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 @@ -1969,8 +1920,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); } @@ -2132,8 +2083,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); @@ -2193,7 +2144,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. @@ -2237,6 +2189,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)); @@ -2244,10 +2212,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)); @@ -2287,18 +2257,26 @@ void Builtins::Generate_Apply(MacroAssembler* masm) { // Push arguments onto the stack (thisArgument is already on the stack). { __ movd(xmm0, edx); + __ movd(xmm1, edi); __ 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); + __ movd(edi, xmm1); __ movd(edx, xmm0); __ Move(eax, ebx); } |