| 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 |