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 |