| OLD | NEW |
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
| 6 // are met: | 6 // are met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
| 31 // OF THE POSSIBILITY OF SUCH DAMAGE. | 31 // OF THE POSSIBILITY OF SUCH DAMAGE. |
| 32 | 32 |
| 33 // The original source code covered by the above license above has been modified | 33 // The original source code covered by the above license above has been modified |
| 34 // significantly by Google Inc. | 34 // significantly by Google Inc. |
| 35 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 35 // Copyright 2010 the V8 project authors. All rights reserved. |
| 36 | 36 |
| 37 #include "v8.h" | 37 #include "v8.h" |
| 38 | 38 |
| 39 #if defined(V8_TARGET_ARCH_IA32) | 39 #if defined(V8_TARGET_ARCH_IA32) |
| 40 | 40 |
| 41 #include "disassembler.h" | 41 #include "disassembler.h" |
| 42 #include "macro-assembler.h" | 42 #include "macro-assembler.h" |
| 43 #include "serialize.h" | 43 #include "serialize.h" |
| 44 | 44 |
| 45 namespace v8 { | 45 namespace v8 { |
| 46 namespace internal { | 46 namespace internal { |
| 47 | 47 |
| 48 // ----------------------------------------------------------------------------- | 48 // ----------------------------------------------------------------------------- |
| 49 // Implementation of CpuFeatures | 49 // Implementation of CpuFeatures |
| 50 | 50 |
| 51 CpuFeatures::CpuFeatures() | 51 CpuFeatures::CpuFeatures() |
| 52 : supported_(0), | 52 : supported_(0), |
| 53 enabled_(0), | 53 enabled_(0), |
| 54 found_by_runtime_probing_(0) { | 54 found_by_runtime_probing_(0) { |
| 55 } | 55 } |
| 56 | 56 |
| 57 |
| 57 // The Probe method needs executable memory, so it uses Heap::CreateCode. | 58 // The Probe method needs executable memory, so it uses Heap::CreateCode. |
| 58 // Allocation failure is silent and leads to safe default. | 59 // Allocation failure is silent and leads to safe default. |
| 59 void CpuFeatures::Probe() { | 60 void CpuFeatures::Probe(bool portable) { |
| 60 ASSERT(HEAP->HasBeenSetup()); | 61 ASSERT(HEAP->HasBeenSetup()); |
| 61 ASSERT(supported_ == 0); | 62 ASSERT(supported_ == 0); |
| 62 if (Serializer::enabled()) { | 63 if (portable && Serializer::enabled()) { |
| 63 supported_ |= OS::CpuFeaturesImpliedByPlatform(); | 64 supported_ |= OS::CpuFeaturesImpliedByPlatform(); |
| 64 return; // No features if we might serialize. | 65 return; // No features if we might serialize. |
| 65 } | 66 } |
| 66 | 67 |
| 67 Assembler assm(NULL, 0); | 68 Assembler assm(NULL, 0); |
| 68 Label cpuid, done; | 69 Label cpuid, done; |
| 69 #define __ assm. | 70 #define __ assm. |
| 70 // Save old esp, since we are going to modify the stack. | 71 // Save old esp, since we are going to modify the stack. |
| 71 __ push(ebp); | 72 __ push(ebp); |
| 72 __ pushfd(); | 73 __ pushfd(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 if (!code->IsCode()) return; | 130 if (!code->IsCode()) return; |
| 130 | 131 |
| 131 PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG, | 132 PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG, |
| 132 Code::cast(code), "CpuFeatures::Probe")); | 133 Code::cast(code), "CpuFeatures::Probe")); |
| 133 typedef uint64_t (*F0)(); | 134 typedef uint64_t (*F0)(); |
| 134 F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry()); | 135 F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry()); |
| 135 supported_ = probe(); | 136 supported_ = probe(); |
| 136 found_by_runtime_probing_ = supported_; | 137 found_by_runtime_probing_ = supported_; |
| 137 uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform(); | 138 uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform(); |
| 138 supported_ |= os_guarantees; | 139 supported_ |= os_guarantees; |
| 139 found_by_runtime_probing_ &= ~os_guarantees; | 140 found_by_runtime_probing_ &= portable ? ~os_guarantees : 0; |
| 140 } | 141 } |
| 141 | 142 |
| 142 | 143 |
| 143 // ----------------------------------------------------------------------------- | 144 // ----------------------------------------------------------------------------- |
| 144 // Implementation of Displacement | 145 // Implementation of Displacement |
| 145 | 146 |
| 146 void Displacement::init(Label* L, Type type) { | 147 void Displacement::init(Label* L, Type type) { |
| 147 ASSERT(!L->is_bound()); | 148 ASSERT(!L->is_bound()); |
| 148 int next = 0; | 149 int next = 0; |
| 149 if (L->is_linked()) { | 150 if (L->is_linked()) { |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 if (x.is_int8()) { | 428 if (x.is_int8()) { |
| 428 EMIT(0x6a); | 429 EMIT(0x6a); |
| 429 EMIT(x.x_); | 430 EMIT(x.x_); |
| 430 } else { | 431 } else { |
| 431 EMIT(0x68); | 432 EMIT(0x68); |
| 432 emit(x); | 433 emit(x); |
| 433 } | 434 } |
| 434 } | 435 } |
| 435 | 436 |
| 436 | 437 |
| 438 void Assembler::push_imm32(int32_t imm32) { |
| 439 EnsureSpace ensure_space(this); |
| 440 EMIT(0x68); |
| 441 emit(imm32); |
| 442 } |
| 443 |
| 444 |
| 437 void Assembler::push(Register src) { | 445 void Assembler::push(Register src) { |
| 438 EnsureSpace ensure_space(this); | 446 EnsureSpace ensure_space(this); |
| 439 last_pc_ = pc_; | 447 last_pc_ = pc_; |
| 440 EMIT(0x50 | src.code()); | 448 EMIT(0x50 | src.code()); |
| 441 } | 449 } |
| 442 | 450 |
| 443 | 451 |
| 444 void Assembler::push(const Operand& src) { | 452 void Assembler::push(const Operand& src) { |
| 445 EnsureSpace ensure_space(this); | 453 EnsureSpace ensure_space(this); |
| 446 last_pc_ = pc_; | 454 last_pc_ = pc_; |
| (...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1534 while (L->unresolved_branches_ > 0) { | 1542 while (L->unresolved_branches_ > 0) { |
| 1535 int branch_pos = L->unresolved_positions_[L->unresolved_branches_ - 1]; | 1543 int branch_pos = L->unresolved_positions_[L->unresolved_branches_ - 1]; |
| 1536 int disp = pc_offset() - branch_pos; | 1544 int disp = pc_offset() - branch_pos; |
| 1537 ASSERT(is_int8(disp)); | 1545 ASSERT(is_int8(disp)); |
| 1538 set_byte_at(branch_pos - sizeof(int8_t), disp); | 1546 set_byte_at(branch_pos - sizeof(int8_t), disp); |
| 1539 L->unresolved_branches_--; | 1547 L->unresolved_branches_--; |
| 1540 } | 1548 } |
| 1541 L->bind_to(pc_offset()); | 1549 L->bind_to(pc_offset()); |
| 1542 } | 1550 } |
| 1543 | 1551 |
| 1552 |
| 1544 void Assembler::call(Label* L) { | 1553 void Assembler::call(Label* L) { |
| 1554 positions_recorder()->WriteRecordedPositions(); |
| 1545 EnsureSpace ensure_space(this); | 1555 EnsureSpace ensure_space(this); |
| 1546 last_pc_ = pc_; | 1556 last_pc_ = pc_; |
| 1547 if (L->is_bound()) { | 1557 if (L->is_bound()) { |
| 1548 const int long_size = 5; | 1558 const int long_size = 5; |
| 1549 int offs = L->pos() - pc_offset(); | 1559 int offs = L->pos() - pc_offset(); |
| 1550 ASSERT(offs <= 0); | 1560 ASSERT(offs <= 0); |
| 1551 // 1110 1000 #32-bit disp. | 1561 // 1110 1000 #32-bit disp. |
| 1552 EMIT(0xE8); | 1562 EMIT(0xE8); |
| 1553 emit(offs - long_size); | 1563 emit(offs - long_size); |
| 1554 } else { | 1564 } else { |
| 1555 // 1110 1000 #32-bit disp. | 1565 // 1110 1000 #32-bit disp. |
| 1556 EMIT(0xE8); | 1566 EMIT(0xE8); |
| 1557 emit_disp(L, Displacement::OTHER); | 1567 emit_disp(L, Displacement::OTHER); |
| 1558 } | 1568 } |
| 1559 } | 1569 } |
| 1560 | 1570 |
| 1561 | 1571 |
| 1562 void Assembler::call(byte* entry, RelocInfo::Mode rmode) { | 1572 void Assembler::call(byte* entry, RelocInfo::Mode rmode) { |
| 1573 positions_recorder()->WriteRecordedPositions(); |
| 1563 EnsureSpace ensure_space(this); | 1574 EnsureSpace ensure_space(this); |
| 1564 last_pc_ = pc_; | 1575 last_pc_ = pc_; |
| 1565 ASSERT(!RelocInfo::IsCodeTarget(rmode)); | 1576 ASSERT(!RelocInfo::IsCodeTarget(rmode)); |
| 1566 EMIT(0xE8); | 1577 EMIT(0xE8); |
| 1567 emit(entry - (pc_ + sizeof(int32_t)), rmode); | 1578 emit(entry - (pc_ + sizeof(int32_t)), rmode); |
| 1568 } | 1579 } |
| 1569 | 1580 |
| 1570 | 1581 |
| 1571 void Assembler::call(const Operand& adr) { | 1582 void Assembler::call(const Operand& adr) { |
| 1583 positions_recorder()->WriteRecordedPositions(); |
| 1572 EnsureSpace ensure_space(this); | 1584 EnsureSpace ensure_space(this); |
| 1573 last_pc_ = pc_; | 1585 last_pc_ = pc_; |
| 1574 EMIT(0xFF); | 1586 EMIT(0xFF); |
| 1575 emit_operand(edx, adr); | 1587 emit_operand(edx, adr); |
| 1576 } | 1588 } |
| 1577 | 1589 |
| 1578 | 1590 |
| 1579 void Assembler::call(Handle<Code> code, RelocInfo::Mode rmode) { | 1591 void Assembler::call(Handle<Code> code, RelocInfo::Mode rmode) { |
| 1580 positions_recorder()->WriteRecordedPositions(); | 1592 positions_recorder()->WriteRecordedPositions(); |
| 1581 EnsureSpace ensure_space(this); | 1593 EnsureSpace ensure_space(this); |
| (...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2412 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(SSE2)); | 2424 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(SSE2)); |
| 2413 EnsureSpace ensure_space(this); | 2425 EnsureSpace ensure_space(this); |
| 2414 last_pc_ = pc_; | 2426 last_pc_ = pc_; |
| 2415 EMIT(0x66); | 2427 EMIT(0x66); |
| 2416 EMIT(0x0F); | 2428 EMIT(0x0F); |
| 2417 EMIT(0x6E); | 2429 EMIT(0x6E); |
| 2418 emit_sse_operand(dst, src); | 2430 emit_sse_operand(dst, src); |
| 2419 } | 2431 } |
| 2420 | 2432 |
| 2421 | 2433 |
| 2434 void Assembler::pand(XMMRegister dst, XMMRegister src) { |
| 2435 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(SSE2)); |
| 2436 EnsureSpace ensure_space(this); |
| 2437 last_pc_ = pc_; |
| 2438 EMIT(0x66); |
| 2439 EMIT(0x0F); |
| 2440 EMIT(0xDB); |
| 2441 emit_sse_operand(dst, src); |
| 2442 } |
| 2443 |
| 2444 |
| 2422 void Assembler::pxor(XMMRegister dst, XMMRegister src) { | 2445 void Assembler::pxor(XMMRegister dst, XMMRegister src) { |
| 2423 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(SSE2)); | 2446 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(SSE2)); |
| 2424 EnsureSpace ensure_space(this); | 2447 EnsureSpace ensure_space(this); |
| 2425 last_pc_ = pc_; | 2448 last_pc_ = pc_; |
| 2426 EMIT(0x66); | 2449 EMIT(0x66); |
| 2427 EMIT(0x0F); | 2450 EMIT(0x0F); |
| 2428 EMIT(0xEF); | 2451 EMIT(0xEF); |
| 2429 emit_sse_operand(dst, src); | 2452 emit_sse_operand(dst, src); |
| 2430 } | 2453 } |
| 2431 | 2454 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2483 | 2506 |
| 2484 | 2507 |
| 2485 void Assembler::RecordDebugBreakSlot() { | 2508 void Assembler::RecordDebugBreakSlot() { |
| 2486 positions_recorder()->WriteRecordedPositions(); | 2509 positions_recorder()->WriteRecordedPositions(); |
| 2487 EnsureSpace ensure_space(this); | 2510 EnsureSpace ensure_space(this); |
| 2488 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); | 2511 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); |
| 2489 } | 2512 } |
| 2490 | 2513 |
| 2491 | 2514 |
| 2492 void Assembler::RecordComment(const char* msg) { | 2515 void Assembler::RecordComment(const char* msg) { |
| 2493 if (FLAG_debug_code) { | 2516 if (FLAG_code_comments) { |
| 2494 EnsureSpace ensure_space(this); | 2517 EnsureSpace ensure_space(this); |
| 2495 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); | 2518 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); |
| 2496 } | 2519 } |
| 2497 } | 2520 } |
| 2498 | 2521 |
| 2499 | 2522 |
| 2500 void Assembler::GrowBuffer() { | 2523 void Assembler::GrowBuffer() { |
| 2501 Isolate* isolate = Isolate::Current(); | 2524 Isolate* isolate = Isolate::Current(); |
| 2502 ASSERT(overflow()); | 2525 ASSERT(overflow()); |
| 2503 if (!own_buffer_) FATAL("external code buffer is too small"); | 2526 if (!own_buffer_) FATAL("external code buffer is too small"); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2617 | 2640 |
| 2618 | 2641 |
| 2619 void Assembler::emit_farith(int b1, int b2, int i) { | 2642 void Assembler::emit_farith(int b1, int b2, int i) { |
| 2620 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode | 2643 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode |
| 2621 ASSERT(0 <= i && i < 8); // illegal stack offset | 2644 ASSERT(0 <= i && i < 8); // illegal stack offset |
| 2622 EMIT(b1); | 2645 EMIT(b1); |
| 2623 EMIT(b2 + i); | 2646 EMIT(b2 + i); |
| 2624 } | 2647 } |
| 2625 | 2648 |
| 2626 | 2649 |
| 2627 void Assembler::dd(uint32_t data, RelocInfo::Mode reloc_info) { | 2650 void Assembler::db(uint8_t data) { |
| 2628 EnsureSpace ensure_space(this); | 2651 EnsureSpace ensure_space(this); |
| 2629 emit(data, reloc_info); | 2652 EMIT(data); |
| 2630 } | 2653 } |
| 2631 | 2654 |
| 2632 | 2655 |
| 2656 void Assembler::dd(uint32_t data) { |
| 2657 EnsureSpace ensure_space(this); |
| 2658 emit(data); |
| 2659 } |
| 2660 |
| 2661 |
| 2633 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { | 2662 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { |
| 2634 ASSERT(rmode != RelocInfo::NONE); | 2663 ASSERT(rmode != RelocInfo::NONE); |
| 2635 // Don't record external references unless the heap will be serialized. | 2664 // Don't record external references unless the heap will be serialized. |
| 2636 if (rmode == RelocInfo::EXTERNAL_REFERENCE) { | 2665 if (rmode == RelocInfo::EXTERNAL_REFERENCE) { |
| 2637 #ifdef DEBUG | 2666 #ifdef DEBUG |
| 2638 if (!Serializer::enabled()) { | 2667 if (!Serializer::enabled()) { |
| 2639 Serializer::TooLateToEnableNow(); | 2668 Serializer::TooLateToEnableNow(); |
| 2640 } | 2669 } |
| 2641 #endif | 2670 #endif |
| 2642 if (!Serializer::enabled() && !FLAG_debug_code) { | 2671 if (!Serializer::enabled() && !FLAG_debug_code) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2669 fprintf(coverage_log, "%s\n", file_line); | 2698 fprintf(coverage_log, "%s\n", file_line); |
| 2670 fflush(coverage_log); | 2699 fflush(coverage_log); |
| 2671 } | 2700 } |
| 2672 } | 2701 } |
| 2673 | 2702 |
| 2674 #endif | 2703 #endif |
| 2675 | 2704 |
| 2676 } } // namespace v8::internal | 2705 } } // namespace v8::internal |
| 2677 | 2706 |
| 2678 #endif // V8_TARGET_ARCH_IA32 | 2707 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |