| 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 |