OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/assembler.h" | 5 #include "vm/assembler.h" |
6 | 6 |
7 #include "platform/utils.h" | 7 #include "platform/utils.h" |
8 #include "vm/cpu.h" | 8 #include "vm/cpu.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/os.h" | 11 #include "vm/os.h" |
12 #include "vm/zone.h" | 12 #include "vm/zone.h" |
13 | 13 |
14 namespace dart { | 14 namespace dart { |
15 | 15 |
16 DEFINE_FLAG(bool, check_code_pointer, false, | 16 DEFINE_FLAG(bool, |
| 17 check_code_pointer, |
| 18 false, |
17 "Verify instructions offset in code object." | 19 "Verify instructions offset in code object." |
18 "NOTE: This breaks the profiler."); | 20 "NOTE: This breaks the profiler."); |
19 DEFINE_FLAG(bool, code_comments, false, | 21 DEFINE_FLAG(bool, |
| 22 code_comments, |
| 23 false, |
20 "Include comments into code and disassembly"); | 24 "Include comments into code and disassembly"); |
21 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS) | 25 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS) |
22 DEFINE_FLAG(bool, use_far_branches, false, | 26 DEFINE_FLAG(bool, |
| 27 use_far_branches, |
| 28 false, |
23 "Enable far branches for ARM and MIPS"); | 29 "Enable far branches for ARM and MIPS"); |
24 #endif | 30 #endif |
25 | 31 |
26 static uword NewContents(intptr_t capacity) { | 32 static uword NewContents(intptr_t capacity) { |
27 Zone* zone = Thread::Current()->zone(); | 33 Zone* zone = Thread::Current()->zone(); |
28 uword result = zone->AllocUnsafe(capacity); | 34 uword result = zone->AllocUnsafe(capacity); |
29 #if defined(DEBUG) | 35 #if defined(DEBUG) |
30 // Initialize the buffer with kBreakPointInstruction to force a break | 36 // Initialize the buffer with kBreakPointInstruction to force a break |
31 // point if we ever execute an uninitialized part of the code buffer. | 37 // point if we ever execute an uninitialized part of the code buffer. |
32 Assembler::InitializeMemoryWithBreakpoints(result, capacity); | 38 Assembler::InitializeMemoryWithBreakpoints(result, capacity); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 has_ensured_capacity_ = false; | 81 has_ensured_capacity_ = false; |
76 fixups_processed_ = false; | 82 fixups_processed_ = false; |
77 #endif | 83 #endif |
78 | 84 |
79 // Verify internal state. | 85 // Verify internal state. |
80 ASSERT(Capacity() == kInitialBufferCapacity); | 86 ASSERT(Capacity() == kInitialBufferCapacity); |
81 ASSERT(Size() == 0); | 87 ASSERT(Size() == 0); |
82 } | 88 } |
83 | 89 |
84 | 90 |
85 AssemblerBuffer::~AssemblerBuffer() { | 91 AssemblerBuffer::~AssemblerBuffer() {} |
86 } | |
87 | 92 |
88 | 93 |
89 void AssemblerBuffer::ProcessFixups(const MemoryRegion& region) { | 94 void AssemblerBuffer::ProcessFixups(const MemoryRegion& region) { |
90 AssemblerFixup* fixup = fixup_; | 95 AssemblerFixup* fixup = fixup_; |
91 while (fixup != NULL) { | 96 while (fixup != NULL) { |
92 fixup->Process(region, fixup->position()); | 97 fixup->Process(region, fixup->position()); |
93 fixup = fixup->previous(); | 98 fixup = fixup->previous(); |
94 } | 99 } |
95 } | 100 } |
96 | 101 |
(...skipping 16 matching lines...) Expand all Loading... |
113 intptr_t old_capacity = Capacity(); | 118 intptr_t old_capacity = Capacity(); |
114 intptr_t new_capacity = | 119 intptr_t new_capacity = |
115 Utils::Minimum(old_capacity * 2, old_capacity + 1 * MB); | 120 Utils::Minimum(old_capacity * 2, old_capacity + 1 * MB); |
116 if (new_capacity < old_capacity) { | 121 if (new_capacity < old_capacity) { |
117 FATAL("Unexpected overflow in AssemblerBuffer::ExtendCapacity"); | 122 FATAL("Unexpected overflow in AssemblerBuffer::ExtendCapacity"); |
118 } | 123 } |
119 | 124 |
120 // Allocate the new data area and copy contents of the old one to it. | 125 // Allocate the new data area and copy contents of the old one to it. |
121 uword new_contents = NewContents(new_capacity); | 126 uword new_contents = NewContents(new_capacity); |
122 memmove(reinterpret_cast<void*>(new_contents), | 127 memmove(reinterpret_cast<void*>(new_contents), |
123 reinterpret_cast<void*>(contents_), | 128 reinterpret_cast<void*>(contents_), old_size); |
124 old_size); | |
125 | 129 |
126 // Compute the relocation delta and switch to the new contents area. | 130 // Compute the relocation delta and switch to the new contents area. |
127 intptr_t delta = new_contents - contents_; | 131 intptr_t delta = new_contents - contents_; |
128 contents_ = new_contents; | 132 contents_ = new_contents; |
129 | 133 |
130 // Update the cursor and recompute the limit. | 134 // Update the cursor and recompute the limit. |
131 cursor_ += delta; | 135 cursor_ += delta; |
132 limit_ = ComputeLimit(new_contents, new_capacity); | 136 limit_ = ComputeLimit(new_contents, new_capacity); |
133 | 137 |
134 // Verify internal state. | 138 // Verify internal state. |
135 ASSERT(Capacity() == new_capacity); | 139 ASSERT(Capacity() == new_capacity); |
136 ASSERT(Size() == old_size); | 140 ASSERT(Size() == old_size); |
137 } | 141 } |
138 | 142 |
139 | 143 |
140 class PatchCodeWithHandle : public AssemblerFixup { | 144 class PatchCodeWithHandle : public AssemblerFixup { |
141 public: | 145 public: |
142 PatchCodeWithHandle(ZoneGrowableArray<intptr_t>* pointer_offsets, | 146 PatchCodeWithHandle(ZoneGrowableArray<intptr_t>* pointer_offsets, |
143 const Object& object) | 147 const Object& object) |
144 : pointer_offsets_(pointer_offsets), object_(object) { | 148 : pointer_offsets_(pointer_offsets), object_(object) {} |
145 } | |
146 | 149 |
147 void Process(const MemoryRegion& region, intptr_t position) { | 150 void Process(const MemoryRegion& region, intptr_t position) { |
148 // Patch the handle into the code. Once the instructions are installed into | 151 // Patch the handle into the code. Once the instructions are installed into |
149 // a raw code object and the pointer offsets are setup, the handle is | 152 // a raw code object and the pointer offsets are setup, the handle is |
150 // resolved. | 153 // resolved. |
151 region.Store<const Object*>(position, &object_); | 154 region.Store<const Object*>(position, &object_); |
152 pointer_offsets_->Add(position); | 155 pointer_offsets_->Add(position); |
153 } | 156 } |
154 | 157 |
155 virtual bool IsPointerOffset() const { return true; } | 158 virtual bool IsPointerOffset() const { return true; } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 | 214 |
212 void Assembler::Comment(const char* format, ...) { | 215 void Assembler::Comment(const char* format, ...) { |
213 if (EmittingComments()) { | 216 if (EmittingComments()) { |
214 char buffer[1024]; | 217 char buffer[1024]; |
215 | 218 |
216 va_list args; | 219 va_list args; |
217 va_start(args, format); | 220 va_start(args, format); |
218 OS::VSNPrint(buffer, sizeof(buffer), format, args); | 221 OS::VSNPrint(buffer, sizeof(buffer), format, args); |
219 va_end(args); | 222 va_end(args); |
220 | 223 |
221 comments_.Add(new CodeComment(buffer_.GetPosition(), | 224 comments_.Add( |
222 String::ZoneHandle(String::New(buffer, | 225 new CodeComment(buffer_.GetPosition(), |
223 Heap::kOld)))); | 226 String::ZoneHandle(String::New(buffer, Heap::kOld)))); |
224 } | 227 } |
225 } | 228 } |
226 | 229 |
227 | 230 |
228 bool Assembler::EmittingComments() { | 231 bool Assembler::EmittingComments() { |
229 return FLAG_code_comments || FLAG_disassemble || FLAG_disassemble_optimized; | 232 return FLAG_code_comments || FLAG_disassemble || FLAG_disassemble_optimized; |
230 } | 233 } |
231 | 234 |
232 | 235 |
233 const Code::Comments& Assembler::GetCodeComments() const { | 236 const Code::Comments& Assembler::GetCodeComments() const { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 | 300 |
298 | 301 |
299 intptr_t ObjectPoolWrapper::FindImmediate(uword imm) { | 302 intptr_t ObjectPoolWrapper::FindImmediate(uword imm) { |
300 return FindObject(ObjectPoolWrapperEntry(imm, ObjectPool::kImmediate), | 303 return FindObject(ObjectPoolWrapperEntry(imm, ObjectPool::kImmediate), |
301 kNotPatchable); | 304 kNotPatchable); |
302 } | 305 } |
303 | 306 |
304 | 307 |
305 intptr_t ObjectPoolWrapper::FindNativeEntry(const ExternalLabel* label, | 308 intptr_t ObjectPoolWrapper::FindNativeEntry(const ExternalLabel* label, |
306 Patchability patchable) { | 309 Patchability patchable) { |
307 return FindObject(ObjectPoolWrapperEntry(label->address(), | 310 return FindObject( |
308 ObjectPool::kNativeEntry), | 311 ObjectPoolWrapperEntry(label->address(), ObjectPool::kNativeEntry), |
309 patchable); | 312 patchable); |
310 } | 313 } |
311 | 314 |
312 | 315 |
313 RawObjectPool* ObjectPoolWrapper::MakeObjectPool() { | 316 RawObjectPool* ObjectPoolWrapper::MakeObjectPool() { |
314 intptr_t len = object_pool_.length(); | 317 intptr_t len = object_pool_.length(); |
315 if (len == 0) { | 318 if (len == 0) { |
316 return Object::empty_object_pool().raw(); | 319 return Object::empty_object_pool().raw(); |
317 } | 320 } |
318 const ObjectPool& result = ObjectPool::Handle(ObjectPool::New(len)); | 321 const ObjectPool& result = ObjectPool::Handle(ObjectPool::New(len)); |
319 const TypedData& info_array = TypedData::Handle(result.info_array()); | 322 const TypedData& info_array = TypedData::Handle(result.info_array()); |
320 for (intptr_t i = 0; i < len; ++i) { | 323 for (intptr_t i = 0; i < len; ++i) { |
321 ObjectPool::EntryType info = object_pool_[i].type_; | 324 ObjectPool::EntryType info = object_pool_[i].type_; |
322 info_array.SetInt8(i, static_cast<int8_t>(info)); | 325 info_array.SetInt8(i, static_cast<int8_t>(info)); |
323 if (info == ObjectPool::kTaggedObject) { | 326 if (info == ObjectPool::kTaggedObject) { |
324 result.SetObjectAt(i, *object_pool_[i].obj_); | 327 result.SetObjectAt(i, *object_pool_[i].obj_); |
325 } else { | 328 } else { |
326 result.SetRawValueAt(i, object_pool_[i].raw_value_); | 329 result.SetRawValueAt(i, object_pool_[i].raw_value_); |
327 } | 330 } |
328 } | 331 } |
329 return result.raw(); | 332 return result.raw(); |
330 } | 333 } |
331 | 334 |
332 | 335 |
333 } // namespace dart | 336 } // namespace dart |
OLD | NEW |