Flutter Engine
The Flutter Engine
runtime_entry.h
Go to the documentation of this file.
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_RUNTIME_ENTRY_H_
6#define RUNTIME_VM_RUNTIME_ENTRY_H_
7
8#include "vm/allocation.h"
9#if !defined(DART_PRECOMPILED_RUNTIME)
11#endif
12#include "vm/flags.h"
13#include "vm/heap/safepoint.h"
14#include "vm/log.h"
15#include "vm/native_arguments.h"
17
18namespace dart {
19
20typedef void (*RuntimeFunction)(NativeArguments arguments);
21
22#if !defined(DART_PRECOMPILED_RUNTIME)
24#else
26#endif
27
28// Class RuntimeEntry is used to encapsulate runtime functions, it includes
29// the entry point for the runtime function and the number of arguments expected
30// by the function.
32 public:
33 RuntimeEntry(const char* name,
34 const void* function,
35 intptr_t argument_count,
36 bool is_leaf,
37 bool is_float,
38 bool can_lazy_deopt)
39 :
40#if !defined(DART_PRECOMPILED_RUNTIME)
42#endif
43 name_(name),
44 function_(function),
45 argument_count_(argument_count),
46 is_leaf_(is_leaf),
47 is_float_(is_float),
48 can_lazy_deopt_(can_lazy_deopt) {
49 }
50
51 const char* name() const { return name_; }
52 const void* function() const { return function_; }
53 intptr_t argument_count() const { return argument_count_; }
54 bool is_leaf() const { return is_leaf_; }
55 bool is_float() const { return is_float_; }
56 bool can_lazy_deopt() const { return can_lazy_deopt_; }
58
59 private:
60 const char* const name_;
61 const void* const function_;
62 const intptr_t argument_count_;
63 const bool is_leaf_;
64 const bool is_float_;
65 const bool can_lazy_deopt_;
66
67 DISALLOW_COPY_AND_ASSIGN(RuntimeEntry);
68};
69
70#ifdef DEBUG
71#define TRACE_RUNTIME_CALL(format, name) \
72 if (FLAG_trace_runtime_calls) { \
73 THR_Print("Runtime call: " format "\n", name); \
74 }
75#else
76#define TRACE_RUNTIME_CALL(format, name) \
77 do { \
78 } while (0)
79#endif
80
81#if defined(USING_SIMULATOR)
82#define CHECK_SIMULATOR_STACK_OVERFLOW() \
83 if (!OSThread::Current()->HasStackHeadroom()) { \
84 Exceptions::ThrowStackOverflow(); \
85 }
86#else
87#define CHECK_SIMULATOR_STACK_OVERFLOW()
88#endif // defined(USING_SIMULATOR)
89
90// Helper macros for declaring and defining runtime entries.
91
92#define DEFINE_RUNTIME_ENTRY_IMPL(name, argument_count, can_lazy_deopt) \
93 extern void DRT_##name(NativeArguments arguments); \
94 extern const RuntimeEntry k##name##RuntimeEntry( \
95 "DRT_" #name, reinterpret_cast<const void*>(DRT_##name), argument_count, \
96 false, false, can_lazy_deopt); \
97 static void DRT_Helper##name(Isolate* isolate, Thread* thread, Zone* zone, \
98 NativeArguments arguments); \
99 void DRT_##name(NativeArguments arguments) { \
100 CHECK_STACK_ALIGNMENT; \
101 /* Tell MemorySanitizer 'arguments' is initialized by generated code. */ \
102 MSAN_UNPOISON(&arguments, sizeof(arguments)); \
103 ASSERT(arguments.ArgCount() == argument_count); \
104 TRACE_RUNTIME_CALL("%s", "" #name); \
105 { \
106 Thread* thread = arguments.thread(); \
107 ASSERT(thread == Thread::Current()); \
108 RuntimeCallDeoptScope runtime_call_deopt_scope( \
109 thread, can_lazy_deopt ? RuntimeCallDeoptAbility::kCanLazyDeopt \
110 : RuntimeCallDeoptAbility::kCannotLazyDeopt); \
111 Isolate* isolate = thread->isolate(); \
112 TransitionGeneratedToVM transition(thread); \
113 StackZone zone(thread); \
114 CHECK_SIMULATOR_STACK_OVERFLOW(); \
115 if (FLAG_deoptimize_on_runtime_call_every > 0) { \
116 OnEveryRuntimeEntryCall(thread, "" #name, can_lazy_deopt); \
117 } \
118 DRT_Helper##name(isolate, thread, zone.GetZone(), arguments); \
119 } \
120 } \
121 static void DRT_Helper##name(Isolate* isolate, Thread* thread, Zone* zone, \
122 NativeArguments arguments)
123
124#define DEFINE_RUNTIME_ENTRY(name, argument_count) \
125 DEFINE_RUNTIME_ENTRY_IMPL(name, argument_count, /*can_lazy_deopt=*/true)
126
127#define DEFINE_RUNTIME_ENTRY_NO_LAZY_DEOPT(name, argument_count) \
128 DEFINE_RUNTIME_ENTRY_IMPL(name, argument_count, /*can_lazy_deopt=*/false)
129
130#define DECLARE_RUNTIME_ENTRY(name) \
131 extern const RuntimeEntry k##name##RuntimeEntry; \
132 extern void DRT_##name(NativeArguments arguments);
133
134#define DEFINE_LEAF_RUNTIME_ENTRY(type, name, argument_count, ...) \
135 extern "C" type DLRT_##name(__VA_ARGS__); \
136 extern const RuntimeEntry k##name##RuntimeEntry( \
137 "DLRT_" #name, reinterpret_cast<const void*>(DLRT_##name), \
138 argument_count, true, false, /*can_lazy_deopt=*/false); \
139 type DLRT_##name(__VA_ARGS__) { \
140 CHECK_STACK_ALIGNMENT; \
141 NoSafepointScope no_safepoint_scope;
142
143#define END_LEAF_RUNTIME_ENTRY }
144
145// TODO(rmacnak): Fix alignment issue on simarm and use
146// DEFINE_LEAF_RUNTIME_ENTRY instead.
147#define DEFINE_RAW_LEAF_RUNTIME_ENTRY(name, argument_count, is_float, func) \
148 extern const RuntimeEntry k##name##RuntimeEntry( \
149 "DFLRT_" #name, reinterpret_cast<const void*>(func), argument_count, \
150 true, is_float, /*can_lazy_deopt=*/false)
151
152#define DECLARE_LEAF_RUNTIME_ENTRY(type, name, ...) \
153 extern const RuntimeEntry k##name##RuntimeEntry; \
154 extern "C" type DLRT_##name(__VA_ARGS__);
155
156// Declare all runtime functions here.
159
160// Expected to be called inside a safepoint.
161extern "C" Thread* DLRT_GetFfiCallbackMetadata(uword trampoline,
162 uword* out_entry_point,
163 uword* out_callback_kind);
164
165extern "C" void DLRT_ExitTemporaryIsolate();
166
167// For creating scoped handles in FFI trampolines.
168extern "C" ApiLocalScope* DLRT_EnterHandleScope(Thread* thread);
169extern "C" void DLRT_ExitHandleScope(Thread* thread);
170extern "C" LocalHandle* DLRT_AllocateHandle(ApiLocalScope* scope);
171
172const char* DeoptReasonToCString(ICData::DeoptReasonId deopt_reason);
173
174void OnEveryRuntimeEntryCall(Thread* thread,
175 const char* runtime_call_name,
176 bool can_lazy_deopt);
177
178void DeoptimizeAt(Thread* mutator_thread,
179 const Code& optimized_code,
180 StackFrame* frame);
182
183double DartModulo(double a, double b);
184
185} // namespace dart
186
187#endif // RUNTIME_VM_RUNTIME_ENTRY_H_
bool is_float() const
Definition: runtime_entry.h:55
intptr_t argument_count() const
Definition: runtime_entry.h:53
const void * function() const
Definition: runtime_entry.h:52
const char * name() const
Definition: runtime_entry.h:51
RuntimeEntry(const char *name, const void *function, intptr_t argument_count, bool is_leaf, bool is_float, bool can_lazy_deopt)
Definition: runtime_entry.h:33
uword GetEntryPoint() const
bool can_lazy_deopt() const
Definition: runtime_entry.h:56
bool is_leaf() const
Definition: runtime_entry.h:54
double frame
Definition: examples.cpp:31
static bool b
struct MyStruct a[10]
if(end==-1)
Definition: dart_vm.cc:33
void DeoptimizeFunctionsOnStack()
Thread * DLRT_GetFfiCallbackMetadata(FfiCallbackMetadata::Trampoline trampoline, uword *out_entry_point, uword *out_trampoline_type)
double DartModulo(double left, double right)
void(* RuntimeFunction)(NativeArguments arguments)
Definition: runtime_entry.h:20
void DLRT_ExitHandleScope(Thread *thread)
LocalHandle * DLRT_AllocateHandle(ApiLocalScope *scope)
uintptr_t uword
Definition: globals.h:501
void DLRT_ExitTemporaryIsolate()
ApiLocalScope * DLRT_EnterHandleScope(Thread *thread)
void DeoptimizeAt(Thread *mutator_thread, const Code &optimized_code, StackFrame *frame)
const char * DeoptReasonToCString(ICData::DeoptReasonId deopt_reason)
void OnEveryRuntimeEntryCall(Thread *thread, const char *runtime_call_name, bool can_lazy_deopt)
#define DECLARE_RUNTIME_ENTRY(name)
#define DECLARE_LEAF_RUNTIME_ENTRY(type, name,...)
#define RUNTIME_ENTRY_LIST(V)
#define LEAF_RUNTIME_ENTRY_LIST(V)