| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 37 | 37 |
| 38 // ----------------------------------------------------------------------------- | 38 // ----------------------------------------------------------------------------- |
| 39 // Implementation of CpuFeatures | 39 // Implementation of CpuFeatures |
| 40 | 40 |
| 41 CpuFeatures::CpuFeatures() | 41 CpuFeatures::CpuFeatures() |
| 42 : supported_(kDefaultCpuFeatures), | 42 : supported_(kDefaultCpuFeatures), |
| 43 enabled_(0), | 43 enabled_(0), |
| 44 found_by_runtime_probing_(0) { | 44 found_by_runtime_probing_(0) { |
| 45 } | 45 } |
| 46 | 46 |
| 47 void CpuFeatures::Probe() { | 47 |
| 48 void CpuFeatures::Probe(bool portable) { |
| 48 ASSERT(HEAP->HasBeenSetup()); | 49 ASSERT(HEAP->HasBeenSetup()); |
| 49 ASSERT(supported_ == kDefaultCpuFeatures); | 50 supported_ = kDefaultCpuFeatures; |
| 50 if (Serializer::enabled()) { | 51 if (portable && Serializer::enabled()) { |
| 51 supported_ |= OS::CpuFeaturesImpliedByPlatform(); | 52 supported_ |= OS::CpuFeaturesImpliedByPlatform(); |
| 52 return; // No features if we might serialize. | 53 return; // No features if we might serialize. |
| 53 } | 54 } |
| 54 | 55 |
| 55 Assembler assm(NULL, 0); | 56 Assembler assm(NULL, 0); |
| 56 Label cpuid, done; | 57 Label cpuid, done; |
| 57 #define __ assm. | 58 #define __ assm. |
| 58 // Save old rsp, since we are going to modify the stack. | 59 // Save old rsp, since we are going to modify the stack. |
| 59 __ push(rbp); | 60 __ push(rbp); |
| 60 __ pushfq(); | 61 __ pushfq(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 if (!code->IsCode()) return; | 127 if (!code->IsCode()) return; |
| 127 PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG, | 128 PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG, |
| 128 Code::cast(code), "CpuFeatures::Probe")); | 129 Code::cast(code), "CpuFeatures::Probe")); |
| 129 typedef uint64_t (*F0)(); | 130 typedef uint64_t (*F0)(); |
| 130 F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry()); | 131 F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry()); |
| 131 supported_ = probe(); | 132 supported_ = probe(); |
| 132 found_by_runtime_probing_ = supported_; | 133 found_by_runtime_probing_ = supported_; |
| 133 found_by_runtime_probing_ &= ~kDefaultCpuFeatures; | 134 found_by_runtime_probing_ &= ~kDefaultCpuFeatures; |
| 134 uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform(); | 135 uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform(); |
| 135 supported_ |= os_guarantees; | 136 supported_ |= os_guarantees; |
| 136 found_by_runtime_probing_ &= ~os_guarantees; | 137 found_by_runtime_probing_ &= portable ? ~os_guarantees : 0; |
| 137 // SSE2 and CMOV must be available on an X64 CPU. | 138 // SSE2 and CMOV must be available on an X64 CPU. |
| 138 ASSERT(IsSupported(CPUID)); | 139 ASSERT(IsSupported(CPUID)); |
| 139 ASSERT(IsSupported(SSE2)); | 140 ASSERT(IsSupported(SSE2)); |
| 140 ASSERT(IsSupported(CMOV)); | 141 ASSERT(IsSupported(CMOV)); |
| 141 } | 142 } |
| 142 | 143 |
| 143 | 144 |
| 144 // ----------------------------------------------------------------------------- | 145 // ----------------------------------------------------------------------------- |
| 145 // Implementation of RelocInfo | 146 // Implementation of RelocInfo |
| 146 | 147 |
| (...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 EnsureSpace ensure_space(this); | 818 EnsureSpace ensure_space(this); |
| 818 last_pc_ = pc_; | 819 last_pc_ = pc_; |
| 819 emit_rex_64(src, dst); | 820 emit_rex_64(src, dst); |
| 820 emit(0x0F); | 821 emit(0x0F); |
| 821 emit(0xAB); | 822 emit(0xAB); |
| 822 emit_operand(src, dst); | 823 emit_operand(src, dst); |
| 823 } | 824 } |
| 824 | 825 |
| 825 | 826 |
| 826 void Assembler::call(Label* L) { | 827 void Assembler::call(Label* L) { |
| 828 positions_recorder()->WriteRecordedPositions(); |
| 827 EnsureSpace ensure_space(this); | 829 EnsureSpace ensure_space(this); |
| 828 last_pc_ = pc_; | 830 last_pc_ = pc_; |
| 829 // 1110 1000 #32-bit disp. | 831 // 1110 1000 #32-bit disp. |
| 830 emit(0xE8); | 832 emit(0xE8); |
| 831 if (L->is_bound()) { | 833 if (L->is_bound()) { |
| 832 int offset = L->pos() - pc_offset() - sizeof(int32_t); | 834 int offset = L->pos() - pc_offset() - sizeof(int32_t); |
| 833 ASSERT(offset <= 0); | 835 ASSERT(offset <= 0); |
| 834 emitl(offset); | 836 emitl(offset); |
| 835 } else if (L->is_linked()) { | 837 } else if (L->is_linked()) { |
| 836 emitl(L->pos()); | 838 emitl(L->pos()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 848 positions_recorder()->WriteRecordedPositions(); | 850 positions_recorder()->WriteRecordedPositions(); |
| 849 EnsureSpace ensure_space(this); | 851 EnsureSpace ensure_space(this); |
| 850 last_pc_ = pc_; | 852 last_pc_ = pc_; |
| 851 // 1110 1000 #32-bit disp. | 853 // 1110 1000 #32-bit disp. |
| 852 emit(0xE8); | 854 emit(0xE8); |
| 853 emit_code_target(target, rmode); | 855 emit_code_target(target, rmode); |
| 854 } | 856 } |
| 855 | 857 |
| 856 | 858 |
| 857 void Assembler::call(Register adr) { | 859 void Assembler::call(Register adr) { |
| 860 positions_recorder()->WriteRecordedPositions(); |
| 858 EnsureSpace ensure_space(this); | 861 EnsureSpace ensure_space(this); |
| 859 last_pc_ = pc_; | 862 last_pc_ = pc_; |
| 860 // Opcode: FF /2 r64. | 863 // Opcode: FF /2 r64. |
| 861 emit_optional_rex_32(adr); | 864 emit_optional_rex_32(adr); |
| 862 emit(0xFF); | 865 emit(0xFF); |
| 863 emit_modrm(0x2, adr); | 866 emit_modrm(0x2, adr); |
| 864 } | 867 } |
| 865 | 868 |
| 866 | 869 |
| 867 void Assembler::call(const Operand& op) { | 870 void Assembler::call(const Operand& op) { |
| 871 positions_recorder()->WriteRecordedPositions(); |
| 868 EnsureSpace ensure_space(this); | 872 EnsureSpace ensure_space(this); |
| 869 last_pc_ = pc_; | 873 last_pc_ = pc_; |
| 870 // Opcode: FF /2 m64. | 874 // Opcode: FF /2 m64. |
| 871 emit_optional_rex_32(op); | 875 emit_optional_rex_32(op); |
| 872 emit(0xFF); | 876 emit(0xFF); |
| 873 emit_operand(0x2, op); | 877 emit_operand(0x2, op); |
| 874 } | 878 } |
| 875 | 879 |
| 876 | 880 |
| 877 void Assembler::clc() { | 881 void Assembler::clc() { |
| (...skipping 2051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2929 | 2933 |
| 2930 void Assembler::emit_sse_operand(XMMRegister dst, Register src) { | 2934 void Assembler::emit_sse_operand(XMMRegister dst, Register src) { |
| 2931 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); | 2935 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); |
| 2932 } | 2936 } |
| 2933 | 2937 |
| 2934 void Assembler::emit_sse_operand(Register dst, XMMRegister src) { | 2938 void Assembler::emit_sse_operand(Register dst, XMMRegister src) { |
| 2935 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); | 2939 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); |
| 2936 } | 2940 } |
| 2937 | 2941 |
| 2938 | 2942 |
| 2943 void Assembler::dd(uint32_t data) { |
| 2944 EnsureSpace ensure_space(this); |
| 2945 emitl(data); |
| 2946 } |
| 2947 |
| 2948 |
| 2939 // Relocation information implementations. | 2949 // Relocation information implementations. |
| 2940 | 2950 |
| 2941 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { | 2951 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { |
| 2942 ASSERT(rmode != RelocInfo::NONE); | 2952 ASSERT(rmode != RelocInfo::NONE); |
| 2943 // Don't record external references unless the heap will be serialized. | 2953 // Don't record external references unless the heap will be serialized. |
| 2944 if (rmode == RelocInfo::EXTERNAL_REFERENCE && | 2954 if (rmode == RelocInfo::EXTERNAL_REFERENCE && |
| 2945 !Serializer::enabled() && | 2955 !Serializer::enabled() && |
| 2946 !FLAG_debug_code) { | 2956 !FLAG_debug_code) { |
| 2947 return; | 2957 return; |
| 2948 } | 2958 } |
| 2949 RelocInfo rinfo(pc_, rmode, data); | 2959 RelocInfo rinfo(pc_, rmode, data); |
| 2950 reloc_info_writer.Write(&rinfo); | 2960 reloc_info_writer.Write(&rinfo); |
| 2951 } | 2961 } |
| 2952 | 2962 |
| 2953 void Assembler::RecordJSReturn() { | 2963 void Assembler::RecordJSReturn() { |
| 2954 positions_recorder()->WriteRecordedPositions(); | 2964 positions_recorder()->WriteRecordedPositions(); |
| 2955 EnsureSpace ensure_space(this); | 2965 EnsureSpace ensure_space(this); |
| 2956 RecordRelocInfo(RelocInfo::JS_RETURN); | 2966 RecordRelocInfo(RelocInfo::JS_RETURN); |
| 2957 } | 2967 } |
| 2958 | 2968 |
| 2959 | 2969 |
| 2960 void Assembler::RecordDebugBreakSlot() { | 2970 void Assembler::RecordDebugBreakSlot() { |
| 2961 positions_recorder()->WriteRecordedPositions(); | 2971 positions_recorder()->WriteRecordedPositions(); |
| 2962 EnsureSpace ensure_space(this); | 2972 EnsureSpace ensure_space(this); |
| 2963 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); | 2973 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); |
| 2964 } | 2974 } |
| 2965 | 2975 |
| 2966 | 2976 |
| 2967 void Assembler::RecordComment(const char* msg) { | 2977 void Assembler::RecordComment(const char* msg) { |
| 2968 if (FLAG_debug_code) { | 2978 if (FLAG_code_comments) { |
| 2969 EnsureSpace ensure_space(this); | 2979 EnsureSpace ensure_space(this); |
| 2970 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); | 2980 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg)); |
| 2971 } | 2981 } |
| 2972 } | 2982 } |
| 2973 | 2983 |
| 2974 | 2984 |
| 2975 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | | 2985 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | |
| 2976 1 << RelocInfo::INTERNAL_REFERENCE; | 2986 1 << RelocInfo::INTERNAL_REFERENCE; |
| 2977 | 2987 |
| 2978 | 2988 |
| 2979 bool RelocInfo::IsCodedSpecially() { | 2989 bool RelocInfo::IsCodedSpecially() { |
| 2980 // The deserializer needs to know whether a pointer is specially coded. Being | 2990 // The deserializer needs to know whether a pointer is specially coded. Being |
| 2981 // specially coded on x64 means that it is a relative 32 bit address, as used | 2991 // specially coded on x64 means that it is a relative 32 bit address, as used |
| 2982 // by branch instructions. | 2992 // by branch instructions. |
| 2983 return (1 << rmode_) & kApplyMask; | 2993 return (1 << rmode_) & kApplyMask; |
| 2984 } | 2994 } |
| 2985 | 2995 |
| 2986 | 2996 |
| 2987 | 2997 |
| 2988 } } // namespace v8::internal | 2998 } } // namespace v8::internal |
| 2989 | 2999 |
| 2990 #endif // V8_TARGET_ARCH_X64 | 3000 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |