| 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" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
| 10 #include "vm/memory_region.h" | 10 #include "vm/memory_region.h" |
| 11 #include "vm/runtime_entry.h" | 11 #include "vm/runtime_entry.h" |
| 12 #include "vm/stub_code.h" | 12 #include "vm/stub_code.h" |
| 13 | 13 |
| 14 namespace dart { | 14 namespace dart { |
| 15 | 15 |
| 16 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 16 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| 17 DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available"); | 17 DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available"); |
| 18 DECLARE_FLAG(bool, inline_alloc); |
| 18 | 19 |
| 19 | 20 |
| 20 bool CPUFeatures::sse4_1_supported_ = false; | 21 bool CPUFeatures::sse4_1_supported_ = false; |
| 21 #ifdef DEBUG | 22 #ifdef DEBUG |
| 22 bool CPUFeatures::initialized_ = false; | 23 bool CPUFeatures::initialized_ = false; |
| 23 #endif | 24 #endif |
| 24 | 25 |
| 25 bool CPUFeatures::sse4_1_supported() { | 26 bool CPUFeatures::sse4_1_supported() { |
| 26 DEBUG_ASSERT(initialized_); | 27 DEBUG_ASSERT(initialized_); |
| 27 return sse4_1_supported_ && FLAG_use_sse41; | 28 return sse4_1_supported_ && FLAG_use_sse41; |
| (...skipping 2183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2211 | 2212 |
| 2212 leave(); | 2213 leave(); |
| 2213 } | 2214 } |
| 2214 | 2215 |
| 2215 | 2216 |
| 2216 void Assembler::CallRuntime(const RuntimeEntry& entry) { | 2217 void Assembler::CallRuntime(const RuntimeEntry& entry) { |
| 2217 entry.Call(this); | 2218 entry.Call(this); |
| 2218 } | 2219 } |
| 2219 | 2220 |
| 2220 | 2221 |
| 2222 void Assembler::EnterDartFrame(intptr_t frame_size) { |
| 2223 const intptr_t offset = CodeSize(); |
| 2224 EnterFrame(0); |
| 2225 Label dart_entry; |
| 2226 call(&dart_entry); |
| 2227 Bind(&dart_entry); |
| 2228 // Adjust saved PC for any intrinsic code that could have been generated |
| 2229 // before a frame is created. |
| 2230 if (offset != 0) { |
| 2231 addq(Address(RSP, 0), Immediate(-offset)); |
| 2232 } |
| 2233 if (frame_size != 0) { |
| 2234 subq(RSP, Immediate(frame_size)); |
| 2235 } |
| 2236 } |
| 2237 |
| 2238 |
| 2239 void Assembler::EnterStubFrame() { |
| 2240 EnterFrame(0); |
| 2241 pushq(Immediate(0)); // Push 0 in the saved PC area for stub frames. |
| 2242 } |
| 2243 |
| 2244 |
| 2245 void Assembler::TryAllocate(const Class& cls, |
| 2246 Label* failure, |
| 2247 bool near_jump, |
| 2248 Register instance_reg) { |
| 2249 ASSERT(failure != NULL); |
| 2250 if (FLAG_inline_alloc) { |
| 2251 Heap* heap = Isolate::Current()->heap(); |
| 2252 const intptr_t instance_size = cls.instance_size(); |
| 2253 movq(TMP, Immediate(heap->TopAddress())); |
| 2254 movq(instance_reg, Address(TMP, 0)); |
| 2255 addq(instance_reg, Immediate(instance_size)); |
| 2256 // instance_reg: potential next object start. |
| 2257 movq(TMP, Immediate(heap->EndAddress())); |
| 2258 cmpq(instance_reg, Address(TMP, 0)); |
| 2259 j(ABOVE_EQUAL, failure, near_jump); |
| 2260 // Successfully allocated the object, now update top to point to |
| 2261 // next object start and store the class in the class field of object. |
| 2262 movq(TMP, Immediate(heap->TopAddress())); |
| 2263 movq(Address(TMP, 0), instance_reg); |
| 2264 ASSERT(instance_size >= kHeapObjectTag); |
| 2265 subq(instance_reg, Immediate(instance_size - kHeapObjectTag)); |
| 2266 uword tags = 0; |
| 2267 tags = RawObject::SizeTag::update(instance_size, tags); |
| 2268 ASSERT(cls.id() != kIllegalCid); |
| 2269 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
| 2270 movq(FieldAddress(instance_reg, Object::tags_offset()), Immediate(tags)); |
| 2271 } else { |
| 2272 jmp(failure); |
| 2273 } |
| 2274 } |
| 2275 |
| 2276 |
| 2221 void Assembler::Align(int alignment, int offset) { | 2277 void Assembler::Align(int alignment, int offset) { |
| 2222 ASSERT(Utils::IsPowerOfTwo(alignment)); | 2278 ASSERT(Utils::IsPowerOfTwo(alignment)); |
| 2223 int pos = offset + buffer_.GetPosition(); | 2279 int pos = offset + buffer_.GetPosition(); |
| 2224 int mod = pos & (alignment - 1); | 2280 int mod = pos & (alignment - 1); |
| 2225 if (mod == 0) { | 2281 if (mod == 0) { |
| 2226 return; | 2282 return; |
| 2227 } | 2283 } |
| 2228 int bytes_needed = alignment - mod; | 2284 int bytes_needed = alignment - mod; |
| 2229 while (bytes_needed > MAX_NOP_SIZE) { | 2285 while (bytes_needed > MAX_NOP_SIZE) { |
| 2230 nop(MAX_NOP_SIZE); | 2286 nop(MAX_NOP_SIZE); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2405 | 2461 |
| 2406 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 2462 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 2407 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 2463 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
| 2408 return xmm_reg_names[reg]; | 2464 return xmm_reg_names[reg]; |
| 2409 } | 2465 } |
| 2410 | 2466 |
| 2411 | 2467 |
| 2412 } // namespace dart | 2468 } // namespace dart |
| 2413 | 2469 |
| 2414 #endif // defined TARGET_ARCH_X64 | 2470 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |