diff options
Diffstat (limited to 'deps/v8/src/builtins/x64/builtins-x64.cc')
-rw-r--r-- | deps/v8/src/builtins/x64/builtins-x64.cc | 175 |
1 files changed, 72 insertions, 103 deletions
diff --git a/deps/v8/src/builtins/x64/builtins-x64.cc b/deps/v8/src/builtins/x64/builtins-x64.cc index cde02647ac..1404a9b4c9 100644 --- a/deps/v8/src/builtins/x64/builtins-x64.cc +++ b/deps/v8/src/builtins/x64/builtins-x64.cc @@ -137,8 +137,8 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, // Allocate the new receiver object. __ Push(rdi); __ Push(rdx); - FastNewObjectStub stub(masm->isolate()); - __ CallStub(&stub); + __ Call(CodeFactory::FastNewObject(masm->isolate()).code(), + RelocInfo::CODE_TARGET); __ movp(rbx, rax); __ Pop(rdx); __ Pop(rdi); @@ -151,9 +151,7 @@ void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function, // Retrieve smi-tagged arguments count from the stack. __ SmiToInteger32(rax, Operand(rsp, 0 * kPointerSize)); - } - if (create_implicit_receiver) { // Push the allocated receiver to the stack. We need two copies // because we may have to return the original one and the calling // conventions dictate that the called function pops the receiver. @@ -460,18 +458,18 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { __ movp(FieldOperand(rbx, JSGeneratorObject::kResumeModeOffset), rdx); // Load suspended function and context. - __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset)); __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); + __ movp(rsi, FieldOperand(rdi, 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()); - Operand last_step_action_operand = masm->ExternalOperand(last_step_action); + ExternalReference debug_hook = + ExternalReference::debug_hook_on_function_call_address(masm->isolate()); + Operand debug_hook_operand = masm->ExternalOperand(debug_hook); STATIC_ASSERT(StepFrame > StepIn); - __ cmpb(last_step_action_operand, Immediate(StepIn)); - __ j(greater_equal, &prepare_step_in_if_stepping); + __ cmpb(debug_hook_operand, 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 = @@ -514,14 +512,15 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { __ bind(&done_loop); } - // Dispatch on the kind of generator object. - Label old_generator; - __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); - __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kFunctionDataOffset)); - __ CmpObjectType(rcx, BYTECODE_ARRAY_TYPE, rcx); - __ j(not_equal, &old_generator); + // Underlying function needs to have bytecode available. + if (FLAG_debug_code) { + __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); + __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kFunctionDataOffset)); + __ CmpObjectType(rcx, BYTECODE_ARRAY_TYPE, rcx); + __ Assert(equal, kMissingBytecodeArray); + } - // New-style (ignition/turbofan) generator object. + // Resume (Ignition/TurboFan) generator object. { __ PushReturnAddressFrom(rax); __ movp(rax, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); @@ -534,60 +533,13 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { __ jmp(FieldOperand(rdi, 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(rax); // Return address. - __ Push(rbp); // Caller's frame pointer. - __ Move(rbp, rsp); - __ Push(rsi); // Callee's context. - __ Push(rdi); // Callee's JS Function. - - // Restore the operand stack. - __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kOperandStackOffset)); - __ SmiToInteger32(rax, FieldOperand(rsi, FixedArray::kLengthOffset)); - { - Label done_loop, loop; - __ Set(rcx, 0); - __ bind(&loop); - __ cmpl(rcx, rax); - __ j(equal, &done_loop, Label::kNear); - __ Push( - FieldOperand(rsi, rcx, times_pointer_size, FixedArray::kHeaderSize)); - __ addl(rcx, Immediate(1)); - __ jmp(&loop); - __ bind(&done_loop); - } - - // Reset operand stack so we don't leak. - __ LoadRoot(FieldOperand(rbx, JSGeneratorObject::kOperandStackOffset), - Heap::kEmptyFixedArrayRootIndex); - - // Restore context. - __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset)); - - // Resume the generator function at the continuation. - __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); - __ movp(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset)); - __ SmiToInteger64( - rcx, FieldOperand(rbx, JSGeneratorObject::kContinuationOffset)); - __ leap(rdx, FieldOperand(rdx, rcx, times_1, Code::kHeaderSize)); - __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), - Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)); - __ 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); + __ CallRuntime(Runtime::kDebugOnFunctionCall); __ Pop(rdx); __ Pop(rbx); __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); @@ -689,6 +641,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); } + // Reset code age. + __ movb(FieldOperand(kInterpreterBytecodeArrayRegister, + BytecodeArray::kBytecodeAgeOffset), + Immediate(BytecodeArray::kNoAgeBytecodeAge)); + // Load initial bytecode offset. __ movp(kInterpreterBytecodeOffsetRegister, Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag)); @@ -1060,13 +1017,6 @@ void Builtins::Generate_CompileLazy(MacroAssembler* masm) { __ movp(temp, FieldOperand(temp, WeakCell::kValueOffset)); __ cmpp(temp, native_context); __ j(not_equal, &loop_bottom); - // OSR id set to none? - __ movp(temp, FieldOperand(map, index, times_pointer_size, - SharedFunctionInfo::kOffsetToPreviousOsrAstId)); - __ SmiToInteger32(temp, temp); - const int bailout_id = BailoutId::None().ToInt(); - __ cmpl(temp, Immediate(bailout_id)); - __ j(not_equal, &loop_bottom); // Literals available? __ movp(temp, FieldOperand(map, index, times_pointer_size, SharedFunctionInfo::kOffsetToPreviousLiterals)); @@ -1126,14 +1076,14 @@ void Builtins::Generate_CompileLazy(MacroAssembler* masm) { __ testb(FieldOperand(entry, SharedFunctionInfo::kMarkedForTierUpByteOffset), Immediate(1 << SharedFunctionInfo::kMarkedForTierUpBitWithinByte)); __ j(not_zero, &gotta_call_runtime); - // Is the full code valid? + + // If SFI points to anything other than CompileLazy, install that. __ movp(entry, FieldOperand(entry, SharedFunctionInfo::kCodeOffset)); - __ movl(rbx, FieldOperand(entry, Code::kFlagsOffset)); - __ andl(rbx, Immediate(Code::KindField::kMask)); - __ shrl(rbx, Immediate(Code::KindField::kShift)); - __ cmpl(rbx, Immediate(Code::BUILTIN)); + __ Move(rbx, masm->CodeObject()); + __ cmpp(entry, rbx); __ j(equal, &gotta_call_runtime); - // Yes, install the full code. + + // Install the SFI's code entry. __ leap(entry, FieldOperand(entry, Code::kHeaderSize)); __ movp(FieldOperand(closure, JSFunction::kCodeEntryOffset), entry); __ RecordWriteCodeEntryField(closure, entry, r15); @@ -1166,7 +1116,7 @@ void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { { FrameScope scope(masm, StackFrame::INTERNAL); // Preserve argument count for later compare. - __ movp(kScratchRegister, rax); + __ movp(rcx, rax); // Push the number of arguments to the callee. __ Integer32ToSmi(rax, rax); __ Push(rax); @@ -1181,7 +1131,7 @@ void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { for (int j = 0; j < 4; ++j) { Label over; if (j < 3) { - __ cmpp(kScratchRegister, Immediate(j)); + __ cmpp(rcx, Immediate(j)); __ j(not_equal, &over, Label::kNear); } for (int i = j - 1; i >= 0; --i) { @@ -1204,13 +1154,13 @@ void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { __ JumpIfSmi(rax, &failed, Label::kNear); __ Drop(2); - __ Pop(kScratchRegister); - __ SmiToInteger32(kScratchRegister, kScratchRegister); + __ Pop(rcx); + __ SmiToInteger32(rcx, rcx); scope.GenerateLeaveFrame(); __ PopReturnAddressTo(rbx); - __ incp(kScratchRegister); - __ leap(rsp, Operand(rsp, kScratchRegister, times_pointer_size, 0)); + __ incp(rcx); + __ leap(rsp, Operand(rsp, rcx, times_pointer_size, 0)); __ PushReturnAddressFrom(rbx); __ ret(0); @@ -1248,14 +1198,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 @@ -1931,8 +1876,8 @@ void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { FrameScope scope(masm, StackFrame::MANUAL); __ EnterBuiltinFrame(rsi, rdi, r8); __ Push(rbx); // the first argument - FastNewObjectStub stub(masm->isolate()); - __ CallStub(&stub); + __ Call(CodeFactory::FastNewObject(masm->isolate()).code(), + RelocInfo::CODE_TARGET); __ Pop(FieldOperand(rax, JSValue::kValueOffset)); __ LeaveBuiltinFrame(rsi, rdi, r8); } @@ -2086,8 +2031,8 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { FrameScope scope(masm, StackFrame::MANUAL); __ EnterBuiltinFrame(rsi, rdi, r8); __ Push(rbx); // the first argument - FastNewObjectStub stub(masm->isolate()); - __ CallStub(&stub); + __ Call(CodeFactory::FastNewObject(masm->isolate()).code(), + RelocInfo::CODE_TARGET); __ Pop(FieldOperand(rax, JSValue::kValueOffset)); __ LeaveBuiltinFrame(rsi, rdi, r8); } @@ -2292,7 +2237,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(rax, &create_runtime); // Load the map of argumentsList into rcx. @@ -2335,6 +2281,21 @@ void Builtins::Generate_Apply(MacroAssembler* masm) { __ movp(rax, rcx); __ jmp(&done_create); + __ bind(&create_holey_array); + // For holey JSArrays we need to check that the array prototype chain + // protector is intact and our prototype is the Array.prototype actually. + __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset)); + __ movp(rcx, FieldOperand(rcx, Map::kPrototypeOffset)); + __ cmpp(rcx, ContextOperand(rbx, Context::INITIAL_ARRAY_PROTOTYPE_INDEX)); + __ j(not_equal, &create_runtime); + __ LoadRoot(rcx, Heap::kArrayProtectorRootIndex); + __ Cmp(FieldOperand(rcx, PropertyCell::kValueOffset), + Smi::FromInt(Isolate::kProtectorValid)); + __ j(not_equal, &create_runtime); + __ SmiToInteger32(rbx, FieldOperand(rax, JSArray::kLengthOffset)); + __ movp(rax, FieldOperand(rax, JSArray::kElementsOffset)); + __ jmp(&done_create); + // Try to create the list from a JSArray object. __ bind(&create_array); __ movzxbp(rcx, FieldOperand(rcx, Map::kBitField2Offset)); @@ -2342,10 +2303,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); - __ cmpl(rcx, Immediate(FAST_ELEMENTS)); - __ j(above, &create_runtime); + STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); __ cmpl(rcx, Immediate(FAST_HOLEY_SMI_ELEMENTS)); - __ j(equal, &create_runtime); + __ j(equal, &create_holey_array); + __ cmpl(rcx, Immediate(FAST_HOLEY_ELEMENTS)); + __ j(equal, &create_holey_array); + __ j(above, &create_runtime); __ SmiToInteger32(rbx, FieldOperand(rax, JSArray::kLengthOffset)); __ movp(rax, FieldOperand(rax, JSArray::kElementsOffset)); @@ -2383,12 +2346,18 @@ void Builtins::Generate_Apply(MacroAssembler* masm) { { __ PopReturnAddressTo(r8); __ Set(rcx, 0); - Label done, loop; + Label done, push, loop; __ bind(&loop); __ cmpl(rcx, rbx); __ j(equal, &done, Label::kNear); - __ Push( - FieldOperand(rax, rcx, times_pointer_size, FixedArray::kHeaderSize)); + // Turn the hole into undefined as we go. + __ movp(r9, FieldOperand(rax, rcx, times_pointer_size, + FixedArray::kHeaderSize)); + __ CompareRoot(r9, Heap::kTheHoleValueRootIndex); + __ j(not_equal, &push, Label::kNear); + __ LoadRoot(r9, Heap::kUndefinedValueRootIndex); + __ bind(&push); + __ Push(r9); __ incl(rcx); __ jmp(&loop); __ bind(&done); |