1 | // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
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. |
4 | |
5 | #ifndef RUNTIME_VM_STUB_CODE_H_ |
6 | #define RUNTIME_VM_STUB_CODE_H_ |
7 | |
8 | #include "vm/allocation.h" |
9 | #include "vm/compiler/runtime_api.h" |
10 | #include "vm/object.h" |
11 | #include "vm/stub_code_list.h" |
12 | |
13 | #if !defined(DART_PRECOMPILED_RUNTIME) |
14 | #include "vm/compiler/assembler/assembler.h" |
15 | #include "vm/compiler/stub_code_compiler.h" |
16 | #endif // !defined(DART_PRECOMPILED_RUNTIME) |
17 | |
18 | namespace dart { |
19 | |
20 | // Forward declarations. |
21 | class Code; |
22 | class Isolate; |
23 | class ObjectPointerVisitor; |
24 | class SnapshotReader; |
25 | class SnapshotWriter; |
26 | |
27 | DECLARE_FLAG(bool, disassemble_stubs); |
28 | |
29 | // Is it permitted for the stubs above to refer to Object::null(), which is |
30 | // allocated in the VM isolate and shared across all isolates. |
31 | // However, in cases where a simple GC-safe placeholder is needed on the stack, |
32 | // using Smi 0 instead of Object::null() is slightly more efficient, since a Smi |
33 | // does not require relocation. |
34 | |
35 | // class StubCode is used to maintain the lifecycle of stubs. |
36 | class StubCode : public AllStatic { |
37 | public: |
38 | // Generate all stubs which are shared across all isolates, this is done |
39 | // only once and the stub code resides in the vm_isolate heap. |
40 | static void Init(); |
41 | |
42 | static void Cleanup(); |
43 | |
44 | // Returns true if stub code has been initialized. |
45 | static bool HasBeenInitialized(); |
46 | |
47 | // Check if specified pc is in the dart invocation stub used for |
48 | // transitioning into dart code. |
49 | static bool InInvocationStub(uword pc, bool is_interpreted_frame); |
50 | |
51 | // Check if the specified pc is in the jump to frame stub. |
52 | static bool InJumpToFrameStub(uword pc); |
53 | |
54 | // Returns NULL if no stub found. |
55 | static const char* NameOfStub(uword entry_point); |
56 | |
57 | // Define the shared stub code accessors. |
58 | #define STUB_CODE_ACCESSOR(name) \ |
59 | static const Code& name() { return *entries_[k##name##Index].code; } \ |
60 | static intptr_t name##Size() { return name().Size(); } |
61 | VM_STUB_CODE_LIST(STUB_CODE_ACCESSOR); |
62 | #undef STUB_CODE_ACCESSOR |
63 | |
64 | static CodePtr GetAllocationStubForClass(const Class& cls); |
65 | |
66 | #if !defined(TARGET_ARCH_IA32) |
67 | static CodePtr (compiler::ObjectPoolBuilder* pool); |
68 | #endif |
69 | |
70 | #if !defined(DART_PRECOMPILED_RUNTIME) |
71 | // Generate the stub and finalize the generated code into the stub |
72 | // code executable area. |
73 | static CodePtr Generate(const char* name, |
74 | compiler::ObjectPoolBuilder* object_pool_builder, |
75 | void (*GenerateStub)(compiler::Assembler* assembler)); |
76 | #endif // !defined(DART_PRECOMPILED_RUNTIME) |
77 | |
78 | static const Code& UnoptimizedStaticCallEntry(intptr_t num_args_tested); |
79 | |
80 | static const char* NameAt(intptr_t index) { return entries_[index].name; } |
81 | |
82 | static const Code& EntryAt(intptr_t index) { return *(entries_[index].code); } |
83 | static void EntryAtPut(intptr_t index, Code* entry) { |
84 | ASSERT(entry->IsReadOnlyHandle()); |
85 | ASSERT(entries_[index].code == nullptr); |
86 | entries_[index].code = entry; |
87 | } |
88 | static intptr_t NumEntries() { return kNumStubEntries; } |
89 | |
90 | #if !defined(DART_PRECOMPILED_RUNTIME) |
91 | #define GENERATE_STUB(name) \ |
92 | static CodePtr BuildIsolateSpecific##name##Stub( \ |
93 | compiler::ObjectPoolBuilder* opw) { \ |
94 | return StubCode::Generate( \ |
95 | "_iso_stub_" #name, opw, \ |
96 | compiler::StubCodeCompiler::Generate##name##Stub); \ |
97 | } |
98 | VM_STUB_CODE_LIST(GENERATE_STUB); |
99 | #undef GENERATE_STUB |
100 | #endif // !defined(DART_PRECOMPILED_RUNTIME) |
101 | |
102 | private: |
103 | friend class MegamorphicCacheTable; |
104 | |
105 | enum { |
106 | #define STUB_CODE_ENTRY(name) k##name##Index, |
107 | VM_STUB_CODE_LIST(STUB_CODE_ENTRY) |
108 | #undef STUB_CODE_ENTRY |
109 | kNumStubEntries |
110 | }; |
111 | |
112 | struct StubCodeEntry { |
113 | Code* code; |
114 | const char* name; |
115 | #if !defined(DART_PRECOMPILED_RUNTIME) |
116 | void (*generator)(compiler::Assembler* assembler); |
117 | #endif |
118 | }; |
119 | static StubCodeEntry entries_[kNumStubEntries]; |
120 | }; |
121 | |
122 | } // namespace dart |
123 | |
124 | #endif // RUNTIME_VM_STUB_CODE_H_ |
125 | |