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/stub_code.h" | 5 #include "vm/stub_code.h" |
6 | 6 |
7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
8 #include "platform/globals.h" | 8 #include "platform/globals.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/disassembler.h" | 10 #include "vm/disassembler.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 label_(code.UncheckedEntryPoint()) {} | 35 label_(code.UncheckedEntryPoint()) {} |
36 | 36 |
37 | 37 |
38 // Visit all object pointers. | 38 // Visit all object pointers. |
39 void StubEntry::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 39 void StubEntry::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
40 ASSERT(visitor != NULL); | 40 ASSERT(visitor != NULL); |
41 visitor->VisitPointer(reinterpret_cast<RawObject**>(&code_)); | 41 visitor->VisitPointer(reinterpret_cast<RawObject**>(&code_)); |
42 } | 42 } |
43 | 43 |
44 | 44 |
| 45 #if defined(DART_PRECOMPILED_RUNTIME) |
| 46 void StubCode::InitOnce() { |
| 47 // Stubs will be loaded from the snapshot. |
| 48 UNREACHABLE(); |
| 49 } |
| 50 #else |
| 51 |
45 #define STUB_CODE_GENERATE(name) \ | 52 #define STUB_CODE_GENERATE(name) \ |
46 code ^= Generate("_stub_" #name, StubCode::Generate##name##Stub); \ | 53 code ^= Generate("_stub_" #name, StubCode::Generate##name##Stub); \ |
47 entries_[k##name##Index] = new StubEntry(code); | 54 entries_[k##name##Index] = new StubEntry(code); |
48 | 55 |
49 | |
50 void StubCode::InitOnce() { | 56 void StubCode::InitOnce() { |
51 #if defined(DART_PRECOMPILED_RUNTIME) | |
52 // Stubs will be loaded from the snapshot. | |
53 UNREACHABLE(); | |
54 #else | |
55 // Generate all the stubs. | 57 // Generate all the stubs. |
56 Code& code = Code::Handle(); | 58 Code& code = Code::Handle(); |
57 VM_STUB_CODE_LIST(STUB_CODE_GENERATE); | 59 VM_STUB_CODE_LIST(STUB_CODE_GENERATE); |
58 #endif // DART_PRECOMPILED_RUNTIME | |
59 } | 60 } |
60 | 61 |
| 62 #undef STUB_CODE_GENERATE |
61 | 63 |
62 #undef STUB_CODE_GENERATE | 64 |
| 65 RawCode* StubCode::Generate(const char* name, |
| 66 void (*GenerateStub)(Assembler* assembler)) { |
| 67 Assembler assembler; |
| 68 GenerateStub(&assembler); |
| 69 const Code& code = |
| 70 Code::Handle(Code::FinalizeCode(name, &assembler, false /* optimized */)); |
| 71 #ifndef PRODUCT |
| 72 if (FLAG_support_disassembler && FLAG_disassemble_stubs) { |
| 73 LogBlock lb; |
| 74 THR_Print("Code for stub '%s': {\n", name); |
| 75 DisassembleToStdout formatter; |
| 76 code.Disassemble(&formatter); |
| 77 THR_Print("}\n"); |
| 78 const ObjectPool& object_pool = ObjectPool::Handle(code.object_pool()); |
| 79 object_pool.DebugPrint(); |
| 80 } |
| 81 #endif // !PRODUCT |
| 82 return code.raw(); |
| 83 } |
| 84 #endif // defined(DART_PRECOMPILED_RUNTIME) |
63 | 85 |
64 | 86 |
65 void StubCode::Init(Isolate* isolate) {} | 87 void StubCode::Init(Isolate* isolate) {} |
66 | 88 |
67 | 89 |
68 void StubCode::VisitObjectPointers(ObjectPointerVisitor* visitor) {} | 90 void StubCode::VisitObjectPointers(ObjectPointerVisitor* visitor) {} |
69 | 91 |
70 | 92 |
71 bool StubCode::HasBeenInitialized() { | 93 bool StubCode::HasBeenInitialized() { |
72 #if !defined(TARGET_ARCH_DBC) | 94 #if !defined(TARGET_ARCH_DBC) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 // These stubs are not used by DBC. | 133 // These stubs are not used by DBC. |
112 #if !defined(TARGET_ARCH_DBC) | 134 #if !defined(TARGET_ARCH_DBC) |
113 Thread* thread = Thread::Current(); | 135 Thread* thread = Thread::Current(); |
114 Zone* zone = thread->zone(); | 136 Zone* zone = thread->zone(); |
115 const Error& error = Error::Handle(zone, cls.EnsureIsFinalized(thread)); | 137 const Error& error = Error::Handle(zone, cls.EnsureIsFinalized(thread)); |
116 ASSERT(error.IsNull()); | 138 ASSERT(error.IsNull()); |
117 if (cls.id() == kArrayCid) { | 139 if (cls.id() == kArrayCid) { |
118 return AllocateArray_entry()->code(); | 140 return AllocateArray_entry()->code(); |
119 } | 141 } |
120 Code& stub = Code::Handle(zone, cls.allocation_stub()); | 142 Code& stub = Code::Handle(zone, cls.allocation_stub()); |
| 143 #if !defined(DART_PRECOMPILED_RUNTIME) |
121 if (stub.IsNull()) { | 144 if (stub.IsNull()) { |
122 Assembler assembler; | 145 Assembler assembler; |
123 const char* name = cls.ToCString(); | 146 const char* name = cls.ToCString(); |
124 StubCode::GenerateAllocationStubForClass(&assembler, cls); | 147 StubCode::GenerateAllocationStubForClass(&assembler, cls); |
125 | 148 |
126 if (thread->IsMutatorThread()) { | 149 if (thread->IsMutatorThread()) { |
127 stub ^= Code::FinalizeCode(name, &assembler, false /* optimized */); | 150 stub ^= Code::FinalizeCode(name, &assembler, false /* optimized */); |
128 // Check if background compilation thread has not already added the stub. | 151 // Check if background compilation thread has not already added the stub. |
129 if (cls.allocation_stub() == Code::null()) { | 152 if (cls.allocation_stub() == Code::null()) { |
130 stub.set_owner(cls); | 153 stub.set_owner(cls); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 LogBlock lb; | 185 LogBlock lb; |
163 THR_Print("Code for allocation stub '%s': {\n", name); | 186 THR_Print("Code for allocation stub '%s': {\n", name); |
164 DisassembleToStdout formatter; | 187 DisassembleToStdout formatter; |
165 stub.Disassemble(&formatter); | 188 stub.Disassemble(&formatter); |
166 THR_Print("}\n"); | 189 THR_Print("}\n"); |
167 const ObjectPool& object_pool = ObjectPool::Handle(stub.object_pool()); | 190 const ObjectPool& object_pool = ObjectPool::Handle(stub.object_pool()); |
168 object_pool.DebugPrint(); | 191 object_pool.DebugPrint(); |
169 } | 192 } |
170 #endif // !PRODUCT | 193 #endif // !PRODUCT |
171 } | 194 } |
| 195 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
172 return stub.raw(); | 196 return stub.raw(); |
173 #endif // !DBC | 197 #endif // !DBC |
174 UNIMPLEMENTED(); | 198 UNIMPLEMENTED(); |
175 return Code::null(); | 199 return Code::null(); |
176 } | 200 } |
177 | 201 |
178 | 202 |
179 const StubEntry* StubCode::UnoptimizedStaticCallEntry( | 203 const StubEntry* StubCode::UnoptimizedStaticCallEntry( |
180 intptr_t num_args_tested) { | 204 intptr_t num_args_tested) { |
181 // These stubs are not used by DBC. | 205 // These stubs are not used by DBC. |
182 #if !defined(TARGET_ARCH_DBC) | 206 #if !defined(TARGET_ARCH_DBC) |
183 switch (num_args_tested) { | 207 switch (num_args_tested) { |
184 case 0: | 208 case 0: |
185 return ZeroArgsUnoptimizedStaticCall_entry(); | 209 return ZeroArgsUnoptimizedStaticCall_entry(); |
186 case 1: | 210 case 1: |
187 return OneArgUnoptimizedStaticCall_entry(); | 211 return OneArgUnoptimizedStaticCall_entry(); |
188 case 2: | 212 case 2: |
189 return TwoArgsUnoptimizedStaticCall_entry(); | 213 return TwoArgsUnoptimizedStaticCall_entry(); |
190 default: | 214 default: |
191 UNIMPLEMENTED(); | 215 UNIMPLEMENTED(); |
192 return NULL; | 216 return NULL; |
193 } | 217 } |
194 #else | 218 #else |
195 return NULL; | 219 return NULL; |
196 #endif | 220 #endif |
197 } | 221 } |
198 | 222 |
199 | 223 |
200 RawCode* StubCode::Generate(const char* name, | |
201 void (*GenerateStub)(Assembler* assembler)) { | |
202 Assembler assembler; | |
203 GenerateStub(&assembler); | |
204 const Code& code = | |
205 Code::Handle(Code::FinalizeCode(name, &assembler, false /* optimized */)); | |
206 #ifndef PRODUCT | |
207 if (FLAG_support_disassembler && FLAG_disassemble_stubs) { | |
208 LogBlock lb; | |
209 THR_Print("Code for stub '%s': {\n", name); | |
210 DisassembleToStdout formatter; | |
211 code.Disassemble(&formatter); | |
212 THR_Print("}\n"); | |
213 const ObjectPool& object_pool = ObjectPool::Handle(code.object_pool()); | |
214 object_pool.DebugPrint(); | |
215 } | |
216 #endif // !PRODUCT | |
217 return code.raw(); | |
218 } | |
219 | |
220 | |
221 const char* StubCode::NameOfStub(uword entry_point) { | 224 const char* StubCode::NameOfStub(uword entry_point) { |
222 #define VM_STUB_CODE_TESTER(name) \ | 225 #define VM_STUB_CODE_TESTER(name) \ |
223 if ((name##_entry() != NULL) && \ | 226 if ((name##_entry() != NULL) && \ |
224 (entry_point == name##_entry()->EntryPoint())) { \ | 227 (entry_point == name##_entry()->EntryPoint())) { \ |
225 return "" #name; \ | 228 return "" #name; \ |
226 } | 229 } |
227 VM_STUB_CODE_LIST(VM_STUB_CODE_TESTER); | 230 VM_STUB_CODE_LIST(VM_STUB_CODE_TESTER); |
228 #undef VM_STUB_CODE_TESTER | 231 #undef VM_STUB_CODE_TESTER |
229 return NULL; | 232 return NULL; |
230 } | 233 } |
231 | 234 |
232 } // namespace dart | 235 } // namespace dart |
OLD | NEW |