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
18namespace dart {
19
20// Forward declarations.
21class Code;
22class Isolate;
23class ObjectPointerVisitor;
24class SnapshotReader;
25class SnapshotWriter;
26
27DECLARE_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.
36class 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 GetBuildMethodExtractorStub(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