OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
8 | 8 |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/heap.h" | 10 #include "src/heap.h" |
11 #include "src/macro-assembler.h" | 11 #include "src/macro-assembler.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 | 16 |
17 // ------------------------------------------------------------------------- | 17 // ------------------------------------------------------------------------- |
18 // Platform-specific RuntimeCallHelper functions. | 18 // Platform-specific RuntimeCallHelper functions. |
19 | 19 |
20 void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { | 20 void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { |
21 masm->EnterFrame(StackFrame::INTERNAL); | 21 masm->EnterFrame(StackFrame::INTERNAL); |
22 ASSERT(!masm->has_frame()); | 22 DCHECK(!masm->has_frame()); |
23 masm->set_has_frame(true); | 23 masm->set_has_frame(true); |
24 } | 24 } |
25 | 25 |
26 | 26 |
27 void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { | 27 void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { |
28 masm->LeaveFrame(StackFrame::INTERNAL); | 28 masm->LeaveFrame(StackFrame::INTERNAL); |
29 ASSERT(masm->has_frame()); | 29 DCHECK(masm->has_frame()); |
30 masm->set_has_frame(false); | 30 masm->set_has_frame(false); |
31 } | 31 } |
32 | 32 |
33 | 33 |
34 #define __ masm. | 34 #define __ masm. |
35 | 35 |
36 | 36 |
37 UnaryMathFunction CreateExpFunction() { | 37 UnaryMathFunction CreateExpFunction() { |
38 // No SSE2 support | 38 // No SSE2 support |
39 return &std::exp; | 39 return &std::exp; |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 __ dec(dst); | 174 __ dec(dst); |
175 __ mov_b(Operand(dst, 0), eax); | 175 __ mov_b(Operand(dst, 0), eax); |
176 __ jmp(&backward_loop_1byte); | 176 __ jmp(&backward_loop_1byte); |
177 } | 177 } |
178 | 178 |
179 __ bind(&pop_and_return); | 179 __ bind(&pop_and_return); |
180 MemMoveEmitPopAndReturn(&masm); | 180 MemMoveEmitPopAndReturn(&masm); |
181 | 181 |
182 CodeDesc desc; | 182 CodeDesc desc; |
183 masm.GetCode(&desc); | 183 masm.GetCode(&desc); |
184 ASSERT(!RelocInfo::RequiresRelocation(desc)); | 184 DCHECK(!RelocInfo::RequiresRelocation(desc)); |
185 CpuFeatures::FlushICache(buffer, actual_size); | 185 CpuFeatures::FlushICache(buffer, actual_size); |
186 base::OS::ProtectCode(buffer, actual_size); | 186 base::OS::ProtectCode(buffer, actual_size); |
187 // TODO(jkummerow): It would be nice to register this code creation event | 187 // TODO(jkummerow): It would be nice to register this code creation event |
188 // with the PROFILE / GDBJIT system. | 188 // with the PROFILE / GDBJIT system. |
189 return FUNCTION_CAST<MemMoveFunction>(buffer); | 189 return FUNCTION_CAST<MemMoveFunction>(buffer); |
190 } | 190 } |
191 | 191 |
192 | 192 |
193 #undef __ | 193 #undef __ |
194 | 194 |
195 // ------------------------------------------------------------------------- | 195 // ------------------------------------------------------------------------- |
196 // Code generators | 196 // Code generators |
197 | 197 |
198 #define __ ACCESS_MASM(masm) | 198 #define __ ACCESS_MASM(masm) |
199 | 199 |
200 | 200 |
201 void ElementsTransitionGenerator::GenerateMapChangeElementsTransition( | 201 void ElementsTransitionGenerator::GenerateMapChangeElementsTransition( |
202 MacroAssembler* masm, | 202 MacroAssembler* masm, |
203 Register receiver, | 203 Register receiver, |
204 Register key, | 204 Register key, |
205 Register value, | 205 Register value, |
206 Register target_map, | 206 Register target_map, |
207 AllocationSiteMode mode, | 207 AllocationSiteMode mode, |
208 Label* allocation_memento_found) { | 208 Label* allocation_memento_found) { |
209 Register scratch = edi; | 209 Register scratch = edi; |
210 ASSERT(!AreAliased(receiver, key, value, target_map, scratch)); | 210 DCHECK(!AreAliased(receiver, key, value, target_map, scratch)); |
211 | 211 |
212 if (mode == TRACK_ALLOCATION_SITE) { | 212 if (mode == TRACK_ALLOCATION_SITE) { |
213 ASSERT(allocation_memento_found != NULL); | 213 DCHECK(allocation_memento_found != NULL); |
214 __ JumpIfJSArrayHasAllocationMemento( | 214 __ JumpIfJSArrayHasAllocationMemento( |
215 receiver, scratch, allocation_memento_found); | 215 receiver, scratch, allocation_memento_found); |
216 } | 216 } |
217 | 217 |
218 // Set transitioned map. | 218 // Set transitioned map. |
219 __ mov(FieldOperand(receiver, HeapObject::kMapOffset), target_map); | 219 __ mov(FieldOperand(receiver, HeapObject::kMapOffset), target_map); |
220 __ RecordWriteField(receiver, | 220 __ RecordWriteField(receiver, |
221 HeapObject::kMapOffset, | 221 HeapObject::kMapOffset, |
222 target_map, | 222 target_map, |
223 scratch, | 223 scratch, |
224 EMIT_REMEMBERED_SET, | 224 EMIT_REMEMBERED_SET, |
225 OMIT_SMI_CHECK); | 225 OMIT_SMI_CHECK); |
226 } | 226 } |
227 | 227 |
228 | 228 |
229 void ElementsTransitionGenerator::GenerateSmiToDouble( | 229 void ElementsTransitionGenerator::GenerateSmiToDouble( |
230 MacroAssembler* masm, | 230 MacroAssembler* masm, |
231 Register receiver, | 231 Register receiver, |
232 Register key, | 232 Register key, |
233 Register value, | 233 Register value, |
234 Register target_map, | 234 Register target_map, |
235 AllocationSiteMode mode, | 235 AllocationSiteMode mode, |
236 Label* fail) { | 236 Label* fail) { |
237 // Return address is on the stack. | 237 // Return address is on the stack. |
238 ASSERT(receiver.is(edx)); | 238 DCHECK(receiver.is(edx)); |
239 ASSERT(key.is(ecx)); | 239 DCHECK(key.is(ecx)); |
240 ASSERT(value.is(eax)); | 240 DCHECK(value.is(eax)); |
241 ASSERT(target_map.is(ebx)); | 241 DCHECK(target_map.is(ebx)); |
242 | 242 |
243 Label loop, entry, convert_hole, gc_required, only_change_map; | 243 Label loop, entry, convert_hole, gc_required, only_change_map; |
244 | 244 |
245 if (mode == TRACK_ALLOCATION_SITE) { | 245 if (mode == TRACK_ALLOCATION_SITE) { |
246 __ JumpIfJSArrayHasAllocationMemento(edx, edi, fail); | 246 __ JumpIfJSArrayHasAllocationMemento(edx, edi, fail); |
247 } | 247 } |
248 | 248 |
249 // Check for empty arrays, which only require a map transition and no changes | 249 // Check for empty arrays, which only require a map transition and no changes |
250 // to the backing store. | 250 // to the backing store. |
251 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 251 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 | 350 |
351 void ElementsTransitionGenerator::GenerateDoubleToObject( | 351 void ElementsTransitionGenerator::GenerateDoubleToObject( |
352 MacroAssembler* masm, | 352 MacroAssembler* masm, |
353 Register receiver, | 353 Register receiver, |
354 Register key, | 354 Register key, |
355 Register value, | 355 Register value, |
356 Register target_map, | 356 Register target_map, |
357 AllocationSiteMode mode, | 357 AllocationSiteMode mode, |
358 Label* fail) { | 358 Label* fail) { |
359 // Return address is on the stack. | 359 // Return address is on the stack. |
360 ASSERT(receiver.is(edx)); | 360 DCHECK(receiver.is(edx)); |
361 ASSERT(key.is(ecx)); | 361 DCHECK(key.is(ecx)); |
362 ASSERT(value.is(eax)); | 362 DCHECK(value.is(eax)); |
363 ASSERT(target_map.is(ebx)); | 363 DCHECK(target_map.is(ebx)); |
364 | 364 |
365 Label loop, entry, convert_hole, gc_required, only_change_map, success; | 365 Label loop, entry, convert_hole, gc_required, only_change_map, success; |
366 | 366 |
367 if (mode == TRACK_ALLOCATION_SITE) { | 367 if (mode == TRACK_ALLOCATION_SITE) { |
368 __ JumpIfJSArrayHasAllocationMemento(edx, edi, fail); | 368 __ JumpIfJSArrayHasAllocationMemento(edx, edi, fail); |
369 } | 369 } |
370 | 370 |
371 // Check for empty arrays, which only require a map transition and no changes | 371 // Check for empty arrays, which only require a map transition and no changes |
372 // to the backing store. | 372 // to the backing store. |
373 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 373 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 times_1, | 579 times_1, |
580 SeqOneByteString::kHeaderSize)); | 580 SeqOneByteString::kHeaderSize)); |
581 __ bind(&done); | 581 __ bind(&done); |
582 } | 582 } |
583 | 583 |
584 | 584 |
585 #undef __ | 585 #undef __ |
586 | 586 |
587 | 587 |
588 CodeAgingHelper::CodeAgingHelper() { | 588 CodeAgingHelper::CodeAgingHelper() { |
589 ASSERT(young_sequence_.length() == kNoCodeAgeSequenceLength); | 589 DCHECK(young_sequence_.length() == kNoCodeAgeSequenceLength); |
590 CodePatcher patcher(young_sequence_.start(), young_sequence_.length()); | 590 CodePatcher patcher(young_sequence_.start(), young_sequence_.length()); |
591 patcher.masm()->push(ebp); | 591 patcher.masm()->push(ebp); |
592 patcher.masm()->mov(ebp, esp); | 592 patcher.masm()->mov(ebp, esp); |
593 patcher.masm()->push(esi); | 593 patcher.masm()->push(esi); |
594 patcher.masm()->push(edi); | 594 patcher.masm()->push(edi); |
595 } | 595 } |
596 | 596 |
597 | 597 |
598 #ifdef DEBUG | 598 #ifdef DEBUG |
599 bool CodeAgingHelper::IsOld(byte* candidate) const { | 599 bool CodeAgingHelper::IsOld(byte* candidate) const { |
600 return *candidate == kCallOpcode; | 600 return *candidate == kCallOpcode; |
601 } | 601 } |
602 #endif | 602 #endif |
603 | 603 |
604 | 604 |
605 bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) { | 605 bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) { |
606 bool result = isolate->code_aging_helper()->IsYoung(sequence); | 606 bool result = isolate->code_aging_helper()->IsYoung(sequence); |
607 ASSERT(result || isolate->code_aging_helper()->IsOld(sequence)); | 607 DCHECK(result || isolate->code_aging_helper()->IsOld(sequence)); |
608 return result; | 608 return result; |
609 } | 609 } |
610 | 610 |
611 | 611 |
612 void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age, | 612 void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age, |
613 MarkingParity* parity) { | 613 MarkingParity* parity) { |
614 if (IsYoungSequence(isolate, sequence)) { | 614 if (IsYoungSequence(isolate, sequence)) { |
615 *age = kNoAgeCodeAge; | 615 *age = kNoAgeCodeAge; |
616 *parity = NO_MARKING_PARITY; | 616 *parity = NO_MARKING_PARITY; |
617 } else { | 617 } else { |
(...skipping 18 matching lines...) Expand all Loading... |
636 Code* stub = GetCodeAgeStub(isolate, age, parity); | 636 Code* stub = GetCodeAgeStub(isolate, age, parity); |
637 CodePatcher patcher(sequence, young_length); | 637 CodePatcher patcher(sequence, young_length); |
638 patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE32); | 638 patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE32); |
639 } | 639 } |
640 } | 640 } |
641 | 641 |
642 | 642 |
643 } } // namespace v8::internal | 643 } } // namespace v8::internal |
644 | 644 |
645 #endif // V8_TARGET_ARCH_X87 | 645 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |