OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // NOLINT | 5 #include "vm/globals.h" // NOLINT |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 2348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2359 } else { | 2359 } else { |
2360 StoreIntoObjectFilterNoSmi(object, value, &done); | 2360 StoreIntoObjectFilterNoSmi(object, value, &done); |
2361 } | 2361 } |
2362 // A store buffer update is required. | 2362 // A store buffer update is required. |
2363 if (value != EDX) { | 2363 if (value != EDX) { |
2364 pushl(EDX); // Preserve EDX. | 2364 pushl(EDX); // Preserve EDX. |
2365 } | 2365 } |
2366 if (object != EDX) { | 2366 if (object != EDX) { |
2367 movl(EDX, object); | 2367 movl(EDX, object); |
2368 } | 2368 } |
2369 call(Address(THR, Thread::update_store_buffer_entry_point_offset())); | 2369 Call(*StubCode::UpdateStoreBuffer_entry()); |
2370 if (value != EDX) { | 2370 if (value != EDX) { |
2371 popl(EDX); // Restore EDX. | 2371 popl(EDX); // Restore EDX. |
2372 } | 2372 } |
2373 Bind(&done); | 2373 Bind(&done); |
2374 } | 2374 } |
2375 | 2375 |
2376 | 2376 |
2377 void Assembler::StoreIntoObjectNoBarrier(Register object, | 2377 void Assembler::StoreIntoObjectNoBarrier(Register object, |
2378 const Address& dest, | 2378 const Address& dest, |
2379 Register value, | 2379 Register value, |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2615 } | 2615 } |
2616 | 2616 |
2617 | 2617 |
2618 void Assembler::CallRuntime(const RuntimeEntry& entry, | 2618 void Assembler::CallRuntime(const RuntimeEntry& entry, |
2619 intptr_t argument_count) { | 2619 intptr_t argument_count) { |
2620 entry.Call(this, argument_count); | 2620 entry.Call(this, argument_count); |
2621 } | 2621 } |
2622 | 2622 |
2623 | 2623 |
2624 void Assembler::Call(const StubEntry& stub_entry) { | 2624 void Assembler::Call(const StubEntry& stub_entry) { |
2625 const Code& target = Code::ZoneHandle(stub_entry.code()); | 2625 const ExternalLabel label(stub_entry.EntryPoint()); |
2626 LoadObject(CODE_REG, target); | 2626 call(&label); |
2627 call(FieldAddress(CODE_REG, Code::entry_point_offset())); | |
2628 } | 2627 } |
2629 | 2628 |
2630 | 2629 |
2631 void Assembler::Jmp(const StubEntry& stub_entry) { | 2630 void Assembler::Jmp(const StubEntry& stub_entry) { |
2632 const ExternalLabel label(stub_entry.EntryPoint()); | 2631 const ExternalLabel label(stub_entry.EntryPoint()); |
2633 jmp(&label); | 2632 jmp(&label); |
2634 } | 2633 } |
2635 | 2634 |
2636 | 2635 |
2637 void Assembler::J(Condition condition, const StubEntry& stub_entry) { | 2636 void Assembler::J(Condition condition, const StubEntry& stub_entry) { |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2863 uword tags = 0; | 2862 uword tags = 0; |
2864 tags = RawObject::ClassIdTag::update(cid, tags); | 2863 tags = RawObject::ClassIdTag::update(cid, tags); |
2865 tags = RawObject::SizeTag::update(instance_size, tags); | 2864 tags = RawObject::SizeTag::update(instance_size, tags); |
2866 movl(FieldAddress(instance, Object::tags_offset()), Immediate(tags)); | 2865 movl(FieldAddress(instance, Object::tags_offset()), Immediate(tags)); |
2867 } else { | 2866 } else { |
2868 jmp(failure); | 2867 jmp(failure); |
2869 } | 2868 } |
2870 } | 2869 } |
2871 | 2870 |
2872 | 2871 |
2873 void Assembler::PushCodeObject() { | |
2874 ASSERT(code_.IsNotTemporaryScopedHandle()); | |
2875 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | |
2876 EmitUint8(0x68); | |
2877 buffer_.EmitObject(code_); | |
2878 } | |
2879 | |
2880 | |
2881 void Assembler::EnterDartFrame(intptr_t frame_size) { | 2872 void Assembler::EnterDartFrame(intptr_t frame_size) { |
2882 EnterFrame(0); | 2873 EnterFrame(0); |
2883 | 2874 Label dart_entry; |
2884 PushCodeObject(); | 2875 call(&dart_entry); |
2885 | 2876 Bind(&dart_entry); |
| 2877 // The runtime system assumes that the code marker address is |
| 2878 // kEntryPointToPcMarkerOffset bytes from the entry. If there is any code |
| 2879 // generated before entering the frame, the address needs to be adjusted. |
| 2880 const intptr_t offset = EntryPointToPcMarkerOffset() - CodeSize(); |
| 2881 if (offset != 0) { |
| 2882 addl(Address(ESP, 0), Immediate(offset)); |
| 2883 } |
2886 if (frame_size != 0) { | 2884 if (frame_size != 0) { |
2887 subl(ESP, Immediate(frame_size)); | 2885 subl(ESP, Immediate(frame_size)); |
2888 } | 2886 } |
2889 } | 2887 } |
2890 | 2888 |
2891 | 2889 |
2892 // On entry to a function compiled for OSR, the caller's frame pointer, the | 2890 // On entry to a function compiled for OSR, the caller's frame pointer, the |
2893 // stack locals, and any copied parameters are already in place. The frame | 2891 // stack locals, and any copied parameters are already in place. The frame |
2894 // pointer is already set up. There may be extra space for spill slots to | 2892 // pointer is already set up. The PC marker is not correct for the |
| 2893 // optimized function and there may be extra space for spill slots to |
2895 // allocate. | 2894 // allocate. |
2896 void Assembler::EnterOsrFrame(intptr_t extra_size) { | 2895 void Assembler::EnterOsrFrame(intptr_t extra_size) { |
2897 Comment("EnterOsrFrame"); | 2896 Comment("EnterOsrFrame"); |
2898 if (prologue_offset_ == -1) { | 2897 if (prologue_offset_ == -1) { |
2899 Comment("PrologueOffset = %" Pd "", CodeSize()); | 2898 Comment("PrologueOffset = %" Pd "", CodeSize()); |
2900 prologue_offset_ = CodeSize(); | 2899 prologue_offset_ = CodeSize(); |
2901 } | 2900 } |
2902 | 2901 Label dart_entry; |
| 2902 call(&dart_entry); |
| 2903 Bind(&dart_entry); |
| 2904 // The runtime system assumes that the code marker address is |
| 2905 // kEntryPointToPcMarkerOffset bytes from the entry. Since there is no |
| 2906 // code to set up the frame pointer, the address needs to be adjusted. |
| 2907 const intptr_t offset = EntryPointToPcMarkerOffset() - CodeSize(); |
| 2908 if (offset != 0) { |
| 2909 addl(Address(ESP, 0), Immediate(offset)); |
| 2910 } |
| 2911 popl(Address(EBP, kPcMarkerSlotFromFp * kWordSize)); |
2903 if (extra_size != 0) { | 2912 if (extra_size != 0) { |
2904 subl(ESP, Immediate(extra_size)); | 2913 subl(ESP, Immediate(extra_size)); |
2905 } | 2914 } |
2906 } | 2915 } |
2907 | 2916 |
2908 | 2917 |
2909 void Assembler::EnterStubFrame() { | 2918 void Assembler::EnterStubFrame() { |
2910 EnterDartFrame(0); | 2919 EnterFrame(0); |
| 2920 pushl(Immediate(0)); // Push 0 in the saved PC area for stub frames. |
2911 } | 2921 } |
2912 | 2922 |
2913 | 2923 |
2914 void Assembler::Stop(const char* message) { | 2924 void Assembler::Stop(const char* message) { |
2915 if (FLAG_print_stop_message) { | 2925 if (FLAG_print_stop_message) { |
2916 pushl(EAX); // Preserve EAX. | 2926 pushl(EAX); // Preserve EAX. |
2917 movl(EAX, Immediate(reinterpret_cast<int32_t>(message))); | 2927 movl(EAX, Immediate(reinterpret_cast<int32_t>(message))); |
2918 Call(*StubCode::PrintStopMessage_entry()); // Passing message in EAX. | 2928 Call(*StubCode::PrintStopMessage_entry()); // Passing message in EAX. |
2919 popl(EAX); // Restore EAX. | 2929 popl(EAX); // Restore EAX. |
2920 } else { | 2930 } else { |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3206 | 3216 |
3207 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3217 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
3208 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 3218 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
3209 return xmm_reg_names[reg]; | 3219 return xmm_reg_names[reg]; |
3210 } | 3220 } |
3211 | 3221 |
3212 | 3222 |
3213 } // namespace dart | 3223 } // namespace dart |
3214 | 3224 |
3215 #endif // defined TARGET_ARCH_IA32 | 3225 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |