| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 Isolate* isolate, | 107 Isolate* isolate, |
| 108 CodeStubInterfaceDescriptor* descriptor) { | 108 CodeStubInterfaceDescriptor* descriptor) { |
| 109 static Register registers[] = { rdx, rax }; | 109 static Register registers[] = { rdx, rax }; |
| 110 descriptor->register_param_count_ = 2; | 110 descriptor->register_param_count_ = 2; |
| 111 descriptor->register_params_ = registers; | 111 descriptor->register_params_ = registers; |
| 112 descriptor->deoptimization_handler_ = | 112 descriptor->deoptimization_handler_ = |
| 113 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); | 113 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); |
| 114 } | 114 } |
| 115 | 115 |
| 116 | 116 |
| 117 void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor( |
| 118 Isolate* isolate, |
| 119 CodeStubInterfaceDescriptor* descriptor) { |
| 120 static Register registers[] = { rdx, rax }; |
| 121 descriptor->register_param_count_ = 2; |
| 122 descriptor->register_params_ = registers; |
| 123 descriptor->deoptimization_handler_ = |
| 124 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); |
| 125 } |
| 126 |
| 127 |
| 117 void LoadFieldStub::InitializeInterfaceDescriptor( | 128 void LoadFieldStub::InitializeInterfaceDescriptor( |
| 118 Isolate* isolate, | 129 Isolate* isolate, |
| 119 CodeStubInterfaceDescriptor* descriptor) { | 130 CodeStubInterfaceDescriptor* descriptor) { |
| 120 static Register registers[] = { rax }; | 131 static Register registers[] = { rax }; |
| 121 descriptor->register_param_count_ = 1; | 132 descriptor->register_param_count_ = 1; |
| 122 descriptor->register_params_ = registers; | 133 descriptor->register_params_ = registers; |
| 123 descriptor->deoptimization_handler_ = NULL; | 134 descriptor->deoptimization_handler_ = NULL; |
| 124 } | 135 } |
| 125 | 136 |
| 126 | 137 |
| 127 void KeyedLoadFieldStub::InitializeInterfaceDescriptor( | 138 void KeyedLoadFieldStub::InitializeInterfaceDescriptor( |
| 128 Isolate* isolate, | 139 Isolate* isolate, |
| 129 CodeStubInterfaceDescriptor* descriptor) { | 140 CodeStubInterfaceDescriptor* descriptor) { |
| 130 static Register registers[] = { rdx }; | 141 static Register registers[] = { rdx }; |
| 131 descriptor->register_param_count_ = 1; | 142 descriptor->register_param_count_ = 1; |
| 132 descriptor->register_params_ = registers; | 143 descriptor->register_params_ = registers; |
| 133 descriptor->deoptimization_handler_ = NULL; | 144 descriptor->deoptimization_handler_ = NULL; |
| 134 } | 145 } |
| 135 | 146 |
| 136 | 147 |
| 148 void KeyedArrayCallStub::InitializeInterfaceDescriptor( |
| 149 Isolate* isolate, |
| 150 CodeStubInterfaceDescriptor* descriptor) { |
| 151 static Register registers[] = { rcx }; |
| 152 descriptor->register_param_count_ = 1; |
| 153 descriptor->register_params_ = registers; |
| 154 descriptor->continuation_type_ = TAIL_CALL_CONTINUATION; |
| 155 descriptor->handler_arguments_mode_ = PASS_ARGUMENTS; |
| 156 descriptor->deoptimization_handler_ = |
| 157 FUNCTION_ADDR(KeyedCallIC_MissFromStubFailure); |
| 158 } |
| 159 |
| 160 |
| 137 void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( | 161 void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( |
| 138 Isolate* isolate, | 162 Isolate* isolate, |
| 139 CodeStubInterfaceDescriptor* descriptor) { | 163 CodeStubInterfaceDescriptor* descriptor) { |
| 140 static Register registers[] = { rdx, rcx, rax }; | 164 static Register registers[] = { rdx, rcx, rax }; |
| 141 descriptor->register_param_count_ = 3; | 165 descriptor->register_param_count_ = 3; |
| 142 descriptor->register_params_ = registers; | 166 descriptor->register_params_ = registers; |
| 143 descriptor->deoptimization_handler_ = | 167 descriptor->deoptimization_handler_ = |
| 144 FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure); | 168 FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure); |
| 145 } | 169 } |
| 146 | 170 |
| (...skipping 4070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4217 __ j(less, ©_routine); | 4241 __ j(less, ©_routine); |
| 4218 // Allocate new sliced string. At this point we do not reload the instance | 4242 // Allocate new sliced string. At this point we do not reload the instance |
| 4219 // type including the string encoding because we simply rely on the info | 4243 // type including the string encoding because we simply rely on the info |
| 4220 // provided by the original string. It does not matter if the original | 4244 // provided by the original string. It does not matter if the original |
| 4221 // string's encoding is wrong because we always have to recheck encoding of | 4245 // string's encoding is wrong because we always have to recheck encoding of |
| 4222 // the newly created string's parent anyways due to externalized strings. | 4246 // the newly created string's parent anyways due to externalized strings. |
| 4223 Label two_byte_slice, set_slice_header; | 4247 Label two_byte_slice, set_slice_header; |
| 4224 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0); | 4248 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0); |
| 4225 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); | 4249 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); |
| 4226 __ testb(rbx, Immediate(kStringEncodingMask)); | 4250 __ testb(rbx, Immediate(kStringEncodingMask)); |
| 4227 // Make long jumps when allocations tracking is on due to | 4251 __ j(zero, &two_byte_slice, Label::kNear); |
| 4228 // RecordObjectAllocation inside MacroAssembler::Allocate. | |
| 4229 Label::Distance jump_distance = | |
| 4230 masm->isolate()->heap_profiler()->is_tracking_allocations() | |
| 4231 ? Label::kFar | |
| 4232 : Label::kNear; | |
| 4233 __ j(zero, &two_byte_slice, jump_distance); | |
| 4234 __ AllocateAsciiSlicedString(rax, rbx, r14, &runtime); | 4252 __ AllocateAsciiSlicedString(rax, rbx, r14, &runtime); |
| 4235 __ jmp(&set_slice_header, jump_distance); | 4253 __ jmp(&set_slice_header, Label::kNear); |
| 4236 __ bind(&two_byte_slice); | 4254 __ bind(&two_byte_slice); |
| 4237 __ AllocateTwoByteSlicedString(rax, rbx, r14, &runtime); | 4255 __ AllocateTwoByteSlicedString(rax, rbx, r14, &runtime); |
| 4238 __ bind(&set_slice_header); | 4256 __ bind(&set_slice_header); |
| 4239 __ Integer32ToSmi(rcx, rcx); | 4257 __ Integer32ToSmi(rcx, rcx); |
| 4240 __ movq(FieldOperand(rax, SlicedString::kLengthOffset), rcx); | 4258 __ movq(FieldOperand(rax, SlicedString::kLengthOffset), rcx); |
| 4241 __ movq(FieldOperand(rax, SlicedString::kHashFieldOffset), | 4259 __ movq(FieldOperand(rax, SlicedString::kHashFieldOffset), |
| 4242 Immediate(String::kEmptyHashField)); | 4260 Immediate(String::kEmptyHashField)); |
| 4243 __ movq(FieldOperand(rax, SlicedString::kParentOffset), rdi); | 4261 __ movq(FieldOperand(rax, SlicedString::kParentOffset), rdi); |
| 4244 __ movq(FieldOperand(rax, SlicedString::kOffsetOffset), rdx); | 4262 __ movq(FieldOperand(rax, SlicedString::kOffsetOffset), rdx); |
| 4245 __ IncrementCounter(counters->sub_string_native(), 1); | 4263 __ IncrementCounter(counters->sub_string_native(), 1); |
| (...skipping 1205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5451 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | 5469 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); |
| 5452 __ PopReturnAddressTo(rcx); | 5470 __ PopReturnAddressTo(rcx); |
| 5453 int additional_offset = function_mode_ == JS_FUNCTION_STUB_MODE | 5471 int additional_offset = function_mode_ == JS_FUNCTION_STUB_MODE |
| 5454 ? kPointerSize | 5472 ? kPointerSize |
| 5455 : 0; | 5473 : 0; |
| 5456 __ lea(rsp, MemOperand(rsp, rbx, times_pointer_size, additional_offset)); | 5474 __ lea(rsp, MemOperand(rsp, rbx, times_pointer_size, additional_offset)); |
| 5457 __ jmp(rcx); // Return to IC Miss stub, continuation still on stack. | 5475 __ jmp(rcx); // Return to IC Miss stub, continuation still on stack. |
| 5458 } | 5476 } |
| 5459 | 5477 |
| 5460 | 5478 |
| 5479 void StubFailureTailCallTrampolineStub::Generate(MacroAssembler* masm) { |
| 5480 CEntryStub ces(1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs); |
| 5481 __ Call(ces.GetCode(masm->isolate()), RelocInfo::CODE_TARGET); |
| 5482 __ movq(rdi, rax); |
| 5483 int parameter_count_offset = |
| 5484 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; |
| 5485 __ movq(rax, MemOperand(rbp, parameter_count_offset)); |
| 5486 // The parameter count above includes the receiver for the arguments passed to |
| 5487 // the deoptimization handler. Subtract the receiver for the parameter count |
| 5488 // for the call. |
| 5489 __ subl(rax, Immediate(1)); |
| 5490 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); |
| 5491 ParameterCount argument_count(rax); |
| 5492 __ InvokeFunction( |
| 5493 rdi, argument_count, JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
| 5494 } |
| 5495 |
| 5496 |
| 5461 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { | 5497 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { |
| 5462 if (masm->isolate()->function_entry_hook() != NULL) { | 5498 if (masm->isolate()->function_entry_hook() != NULL) { |
| 5463 // It's always safe to call the entry hook stub, as the hook itself | 5499 // It's always safe to call the entry hook stub, as the hook itself |
| 5464 // is not allowed to call back to V8. | 5500 // is not allowed to call back to V8. |
| 5465 AllowStubCallsScope allow_stub_calls(masm, true); | 5501 AllowStubCallsScope allow_stub_calls(masm, true); |
| 5466 | 5502 |
| 5467 ProfileEntryHookStub stub; | 5503 ProfileEntryHookStub stub; |
| 5468 masm->CallStub(&stub); | 5504 masm->CallStub(&stub); |
| 5469 } | 5505 } |
| 5470 } | 5506 } |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5586 // Fix kind and retry (only if we have an allocation site in the cell). | 5622 // Fix kind and retry (only if we have an allocation site in the cell). |
| 5587 __ incl(rdx); | 5623 __ incl(rdx); |
| 5588 __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset)); | 5624 __ movq(rcx, FieldOperand(rbx, Cell::kValueOffset)); |
| 5589 if (FLAG_debug_code) { | 5625 if (FLAG_debug_code) { |
| 5590 Handle<Map> allocation_site_map = | 5626 Handle<Map> allocation_site_map = |
| 5591 masm->isolate()->factory()->allocation_site_map(); | 5627 masm->isolate()->factory()->allocation_site_map(); |
| 5592 __ Cmp(FieldOperand(rcx, 0), allocation_site_map); | 5628 __ Cmp(FieldOperand(rcx, 0), allocation_site_map); |
| 5593 __ Assert(equal, kExpectedAllocationSiteInCell); | 5629 __ Assert(equal, kExpectedAllocationSiteInCell); |
| 5594 } | 5630 } |
| 5595 | 5631 |
| 5596 // Save the resulting elements kind in type info | 5632 // Save the resulting elements kind in type info. We can't just store r3 |
| 5597 __ Integer32ToSmi(rdx, rdx); | 5633 // in the AllocationSite::transition_info field because elements kind is |
| 5598 __ movq(FieldOperand(rcx, AllocationSite::kTransitionInfoOffset), rdx); | 5634 // restricted to a portion of the field...upper bits need to be left alone. |
| 5599 __ SmiToInteger32(rdx, rdx); | 5635 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); |
| 5636 __ SmiAddConstant(FieldOperand(rcx, AllocationSite::kTransitionInfoOffset), |
| 5637 Smi::FromInt(kFastElementsKindPackedToHoley)); |
| 5600 | 5638 |
| 5601 __ bind(&normal_sequence); | 5639 __ bind(&normal_sequence); |
| 5602 int last_index = GetSequenceIndexFromFastElementsKind( | 5640 int last_index = GetSequenceIndexFromFastElementsKind( |
| 5603 TERMINAL_FAST_ELEMENTS_KIND); | 5641 TERMINAL_FAST_ELEMENTS_KIND); |
| 5604 for (int i = 0; i <= last_index; ++i) { | 5642 for (int i = 0; i <= last_index; ++i) { |
| 5605 Label next; | 5643 Label next; |
| 5606 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 5644 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 5607 __ cmpl(rdx, Immediate(kind)); | 5645 __ cmpl(rdx, Immediate(kind)); |
| 5608 __ j(not_equal, &next); | 5646 __ j(not_equal, &next); |
| 5609 ArraySingleArgumentConstructorStub stub(kind); | 5647 ArraySingleArgumentConstructorStub stub(kind); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5731 Label no_info; | 5769 Label no_info; |
| 5732 // If the type cell is undefined, or contains anything other than an | 5770 // If the type cell is undefined, or contains anything other than an |
| 5733 // AllocationSite, call an array constructor that doesn't use AllocationSites. | 5771 // AllocationSite, call an array constructor that doesn't use AllocationSites. |
| 5734 __ Cmp(rbx, undefined_sentinel); | 5772 __ Cmp(rbx, undefined_sentinel); |
| 5735 __ j(equal, &no_info); | 5773 __ j(equal, &no_info); |
| 5736 __ movq(rdx, FieldOperand(rbx, Cell::kValueOffset)); | 5774 __ movq(rdx, FieldOperand(rbx, Cell::kValueOffset)); |
| 5737 __ Cmp(FieldOperand(rdx, 0), | 5775 __ Cmp(FieldOperand(rdx, 0), |
| 5738 masm->isolate()->factory()->allocation_site_map()); | 5776 masm->isolate()->factory()->allocation_site_map()); |
| 5739 __ j(not_equal, &no_info); | 5777 __ j(not_equal, &no_info); |
| 5740 | 5778 |
| 5779 // Only look at the lower 16 bits of the transition info. |
| 5741 __ movq(rdx, FieldOperand(rdx, AllocationSite::kTransitionInfoOffset)); | 5780 __ movq(rdx, FieldOperand(rdx, AllocationSite::kTransitionInfoOffset)); |
| 5742 __ SmiToInteger32(rdx, rdx); | 5781 __ SmiToInteger32(rdx, rdx); |
| 5782 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); |
| 5783 __ and_(rdx, Immediate(AllocationSite::ElementsKindBits::kMask)); |
| 5743 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); | 5784 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
| 5744 | 5785 |
| 5745 __ bind(&no_info); | 5786 __ bind(&no_info); |
| 5746 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); | 5787 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
| 5747 } | 5788 } |
| 5748 | 5789 |
| 5749 | 5790 |
| 5750 void InternalArrayConstructorStub::GenerateCase( | 5791 void InternalArrayConstructorStub::GenerateCase( |
| 5751 MacroAssembler* masm, ElementsKind kind) { | 5792 MacroAssembler* masm, ElementsKind kind) { |
| 5752 Label not_zero_case, not_one_case; | 5793 Label not_zero_case, not_one_case; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5835 __ bind(&fast_elements_case); | 5876 __ bind(&fast_elements_case); |
| 5836 GenerateCase(masm, FAST_ELEMENTS); | 5877 GenerateCase(masm, FAST_ELEMENTS); |
| 5837 } | 5878 } |
| 5838 | 5879 |
| 5839 | 5880 |
| 5840 #undef __ | 5881 #undef __ |
| 5841 | 5882 |
| 5842 } } // namespace v8::internal | 5883 } } // namespace v8::internal |
| 5843 | 5884 |
| 5844 #endif // V8_TARGET_ARCH_X64 | 5885 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |