Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: runtime/vm/native_entry.cc

Issue 2793163002: Do not embed is_auto_setup_scope into the compilation of native calls. (Closed)
Patch Set: . Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS 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 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/native_entry.h" 5 #include "vm/native_entry.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 8
9 #include "vm/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/code_patcher.h" 10 #include "vm/code_patcher.h"
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 ASSERT(!lib.IsNull()); 84 ASSERT(!lib.IsNull());
85 const uint8_t* r = ResolveSymbolInLibrary(lib, pc); 85 const uint8_t* r = ResolveSymbolInLibrary(lib, pc);
86 if (r != NULL) { 86 if (r != NULL) {
87 return r; 87 return r;
88 } 88 }
89 } 89 }
90 return NULL; 90 return NULL;
91 } 91 }
92 92
93 93
94 uword NativeEntry::NativeCallWrapperEntry() {
95 uword entry = reinterpret_cast<uword>(NativeEntry::NativeCallWrapper);
96 #if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC)
97 // DBC does not use redirections unlike other simulators.
98 entry = Simulator::RedirectExternalReference(
99 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments);
100 #endif
101 return entry;
102 }
103
104
105 bool NativeEntry::ReturnValueIsError(NativeArguments* arguments) { 94 bool NativeEntry::ReturnValueIsError(NativeArguments* arguments) {
106 RawObject* retval = arguments->ReturnValue(); 95 RawObject* retval = arguments->ReturnValue();
107 return (retval->IsHeapObject() && 96 return (retval->IsHeapObject() &&
108 RawObject::IsErrorClassId(retval->GetClassId())); 97 RawObject::IsErrorClassId(retval->GetClassId()));
109 } 98 }
110 99
111 100
112 void NativeEntry::PropagateErrors(NativeArguments* arguments) { 101 void NativeEntry::PropagateErrors(NativeArguments* arguments) {
113 Thread* thread = arguments->thread(); 102 Thread* thread = arguments->thread();
114 thread->UnwindScopes(thread->top_exit_frame_info()); 103 thread->UnwindScopes(thread->top_exit_frame_info());
115 104
116 // The thread->zone() is different here than before we unwound. 105 // The thread->zone() is different here than before we unwound.
117 const Object& error = 106 const Object& error =
118 Object::Handle(thread->zone(), arguments->ReturnValue()); 107 Object::Handle(thread->zone(), arguments->ReturnValue());
119 Exceptions::PropagateError(Error::Cast(error)); 108 Exceptions::PropagateError(Error::Cast(error));
120 UNREACHABLE(); 109 UNREACHABLE();
121 } 110 }
122 111
123 112
124 void NativeEntry::NativeCallWrapper(Dart_NativeArguments args, 113 uword NativeEntry::NoScopeNativeCallWrapperEntry() {
125 Dart_NativeFunction func) { 114 uword entry = reinterpret_cast<uword>(NativeEntry::NoScopeNativeCallWrapper);
126 CHECK_STACK_ALIGNMENT; 115 #if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC)
127 NativeCallWrapperNoStackCheck(args, func); 116 // DBC does not use redirections unlike other simulators.
117 entry = Simulator::RedirectExternalReference(
118 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments);
119 #endif
120 return entry;
128 } 121 }
129 122
130 123
131 void NativeEntry::NativeCallWrapperNoStackCheck(Dart_NativeArguments args, 124 void NativeEntry::NoScopeNativeCallWrapper(Dart_NativeArguments args,
132 Dart_NativeFunction func) { 125 Dart_NativeFunction func) {
126 CHECK_STACK_ALIGNMENT;
127 NoScopeNativeCallWrapperNoStackCheck(args, func);
128 }
129
130
131 void NativeEntry::NoScopeNativeCallWrapperNoStackCheck(
132 Dart_NativeArguments args,
133 Dart_NativeFunction func) {
133 VERIFY_ON_TRANSITION; 134 VERIFY_ON_TRANSITION;
134 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); 135 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
135 /* Tell MemorySanitizer 'arguments' is initialized by generated code. */ 136 /* Tell MemorySanitizer 'arguments' is initialized by generated code. */
136 MSAN_UNPOISON(arguments, sizeof(*arguments)); 137 MSAN_UNPOISON(arguments, sizeof(*arguments));
137 Thread* thread = arguments->thread(); 138 Thread* thread = arguments->thread();
138 ASSERT(thread->execution_state() == Thread::kThreadInGenerated); 139 ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
139 if (!arguments->IsNativeAutoSetupScope()) { 140 {
140 TransitionGeneratedToNative transition(thread); 141 TransitionGeneratedToNative transition(thread);
141 func(args); 142 func(args);
142 if (ReturnValueIsError(arguments)) { 143 if (ReturnValueIsError(arguments)) {
143 PropagateErrors(arguments); 144 PropagateErrors(arguments);
144 } 145 }
145 } else { 146 }
147 ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
148 VERIFY_ON_TRANSITION;
149 }
150
151
152 uword NativeEntry::AutoScopeNativeCallWrapperEntry() {
153 uword entry =
154 reinterpret_cast<uword>(NativeEntry::AutoScopeNativeCallWrapper);
155 #if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC)
156 // DBC does not use redirections unlike other simulators.
157 entry = Simulator::RedirectExternalReference(
158 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments);
159 #endif
160 return entry;
161 }
162
163
164 void NativeEntry::AutoScopeNativeCallWrapper(Dart_NativeArguments args,
165 Dart_NativeFunction func) {
166 CHECK_STACK_ALIGNMENT;
167 AutoScopeNativeCallWrapperNoStackCheck(args, func);
168 }
169
170
171 void NativeEntry::AutoScopeNativeCallWrapperNoStackCheck(
172 Dart_NativeArguments args,
173 Dart_NativeFunction func) {
174 VERIFY_ON_TRANSITION;
175 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
176 /* Tell MemorySanitizer 'arguments' is initialized by generated code. */
177 MSAN_UNPOISON(arguments, sizeof(*arguments));
178 Thread* thread = arguments->thread();
179 ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
180 {
146 Isolate* isolate = thread->isolate(); 181 Isolate* isolate = thread->isolate();
147 ApiState* state = isolate->api_state(); 182 ApiState* state = isolate->api_state();
148 ASSERT(state != NULL); 183 ASSERT(state != NULL);
149 ApiLocalScope* current_top_scope = thread->api_top_scope(); 184 ApiLocalScope* current_top_scope = thread->api_top_scope();
150 ApiLocalScope* scope = thread->api_reusable_scope(); 185 ApiLocalScope* scope = thread->api_reusable_scope();
151 TRACE_NATIVE_CALL("0x%" Px "", reinterpret_cast<uintptr_t>(func)); 186 TRACE_NATIVE_CALL("0x%" Px "", reinterpret_cast<uintptr_t>(func));
152 TransitionGeneratedToNative transition(thread); 187 TransitionGeneratedToNative transition(thread);
153 if (scope == NULL) { 188 if (scope == NULL) {
154 scope = 189 scope =
155 new ApiLocalScope(current_top_scope, thread->top_exit_frame_info()); 190 new ApiLocalScope(current_top_scope, thread->top_exit_frame_info());
(...skipping 22 matching lines...) Expand all
178 } 213 }
179 ASSERT(thread->execution_state() == Thread::kThreadInGenerated); 214 ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
180 VERIFY_ON_TRANSITION; 215 VERIFY_ON_TRANSITION;
181 } 216 }
182 217
183 218
184 // DBC does not support lazy native call linking. 219 // DBC does not support lazy native call linking.
185 #if !defined(TARGET_ARCH_DBC) 220 #if !defined(TARGET_ARCH_DBC)
186 static NativeFunction ResolveNativeFunction(Zone* zone, 221 static NativeFunction ResolveNativeFunction(Zone* zone,
187 const Function& func, 222 const Function& func,
188 bool* is_bootstrap_native) { 223 bool* is_bootstrap_native,
224 bool* is_auto_scope) {
189 const Class& cls = Class::Handle(zone, func.Owner()); 225 const Class& cls = Class::Handle(zone, func.Owner());
190 const Library& library = Library::Handle(zone, cls.library()); 226 const Library& library = Library::Handle(zone, cls.library());
191 227
192 *is_bootstrap_native = 228 *is_bootstrap_native =
193 Bootstrap::IsBootstapResolver(library.native_entry_resolver()); 229 Bootstrap::IsBootstapResolver(library.native_entry_resolver());
194 230
195 const String& native_name = String::Handle(zone, func.native_name()); 231 const String& native_name = String::Handle(zone, func.native_name());
196 ASSERT(!native_name.IsNull()); 232 ASSERT(!native_name.IsNull());
197 233
198 const int num_params = NativeArguments::ParameterCountForResolution(func); 234 const int num_params = NativeArguments::ParameterCountForResolution(func);
199 bool auto_setup_scope = true;
200 return NativeEntry::ResolveNative(library, native_name, num_params, 235 return NativeEntry::ResolveNative(library, native_name, num_params,
201 &auto_setup_scope); 236 is_auto_scope);
202 } 237 }
203 238
204 239
205 uword NativeEntry::LinkNativeCallEntry() { 240 uword NativeEntry::LinkNativeCallEntry() {
206 uword entry = reinterpret_cast<uword>(NativeEntry::LinkNativeCall); 241 uword entry = reinterpret_cast<uword>(NativeEntry::LinkNativeCall);
207 #if defined(USING_SIMULATOR) 242 #if defined(USING_SIMULATOR)
208 entry = Simulator::RedirectExternalReference( 243 entry = Simulator::RedirectExternalReference(
209 entry, Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments); 244 entry, Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments);
210 #endif 245 #endif
211 return entry; 246 return entry;
212 } 247 }
213 248
214 249
215 void NativeEntry::LinkNativeCall(Dart_NativeArguments args) { 250 void NativeEntry::LinkNativeCall(Dart_NativeArguments args) {
216 CHECK_STACK_ALIGNMENT; 251 CHECK_STACK_ALIGNMENT;
217 VERIFY_ON_TRANSITION; 252 VERIFY_ON_TRANSITION;
218 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); 253 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
219 /* Tell MemorySanitizer 'arguments' is initialized by generated code. */ 254 /* Tell MemorySanitizer 'arguments' is initialized by generated code. */
220 MSAN_UNPOISON(arguments, sizeof(*arguments)); 255 MSAN_UNPOISON(arguments, sizeof(*arguments));
221 TRACE_NATIVE_CALL("%s", "LinkNative"); 256 TRACE_NATIVE_CALL("%s", "LinkNative");
222 257
223 NativeFunction target_function = NULL; 258 NativeFunction target_function = NULL;
224 bool call_through_wrapper = false; 259 bool is_bootstrap_native = false;
260 bool is_auto_scope = true;
225 261
226 { 262 {
227 TransitionGeneratedToVM transition(arguments->thread()); 263 TransitionGeneratedToVM transition(arguments->thread());
228 StackZone zone(arguments->thread()); 264 StackZone stack_zone(arguments->thread());
265 Zone* zone = stack_zone.GetZone();
229 266
230 DartFrameIterator iterator; 267 DartFrameIterator iterator;
231 StackFrame* caller_frame = iterator.NextFrame(); 268 StackFrame* caller_frame = iterator.NextFrame();
232 269
233 const Code& code = Code::Handle(caller_frame->LookupDartCode()); 270 const Code& code = Code::Handle(zone, caller_frame->LookupDartCode());
234 const Function& func = Function::Handle(code.function()); 271 const Function& func = Function::Handle(zone, code.function());
235 272
236 if (FLAG_trace_natives) { 273 if (FLAG_trace_natives) {
237 OS::Print("Resolving native target for %s\n", func.ToCString()); 274 OS::Print("Resolving native target for %s\n", func.ToCString());
238 } 275 }
239 276
240 bool is_bootstrap_native = false; 277 target_function =
241 target_function = ResolveNativeFunction(arguments->thread()->zone(), func, 278 ResolveNativeFunction(arguments->thread()->zone(), func,
242 &is_bootstrap_native); 279 &is_bootstrap_native, &is_auto_scope);
243 ASSERT(target_function != NULL); 280 ASSERT(target_function != NULL);
244 281
245 #if defined(DEBUG) 282 #if defined(DEBUG)
246 { 283 {
247 NativeFunction current_function = NULL; 284 NativeFunction current_function = NULL;
248 const Code& current_trampoline = 285 const Code& current_trampoline =
249 Code::Handle(CodePatcher::GetNativeCallAt(caller_frame->pc(), code, 286 Code::Handle(zone, CodePatcher::GetNativeCallAt(
250 &current_function)); 287 caller_frame->pc(), code, &current_function));
251 #if !defined(USING_SIMULATOR) 288 #if !defined(USING_SIMULATOR)
252 ASSERT(current_function == 289 ASSERT(current_function ==
253 reinterpret_cast<NativeFunction>(LinkNativeCall)); 290 reinterpret_cast<NativeFunction>(LinkNativeCall));
254 #else 291 #else
255 ASSERT( 292 ASSERT(
256 current_function == 293 current_function ==
257 reinterpret_cast<NativeFunction>(Simulator::RedirectExternalReference( 294 reinterpret_cast<NativeFunction>(Simulator::RedirectExternalReference(
258 reinterpret_cast<uword>(LinkNativeCall), 295 reinterpret_cast<uword>(LinkNativeCall),
259 Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments))); 296 Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments)));
260 #endif 297 #endif
261 ASSERT(current_trampoline.raw() == 298 ASSERT(current_trampoline.raw() ==
262 StubCode::CallBootstrapCFunction_entry()->code()); 299 StubCode::CallBootstrapNative_entry()->code());
263 } 300 }
264 #endif 301 #endif
265 302
266 call_through_wrapper = !is_bootstrap_native;
267 const Code& trampoline =
268 Code::Handle(call_through_wrapper
269 ? StubCode::CallNativeCFunction_entry()->code()
270 : StubCode::CallBootstrapCFunction_entry()->code());
271
272 NativeFunction patch_target_function = target_function; 303 NativeFunction patch_target_function = target_function;
304 Code& trampoline = Code::Handle(zone);
305 if (is_bootstrap_native) {
306 trampoline = StubCode::CallBootstrapNative_entry()->code();
273 #if defined(USING_SIMULATOR) 307 #if defined(USING_SIMULATOR)
274 if (!call_through_wrapper) {
275 patch_target_function = 308 patch_target_function =
276 reinterpret_cast<NativeFunction>(Simulator::RedirectExternalReference( 309 reinterpret_cast<NativeFunction>(Simulator::RedirectExternalReference(
277 reinterpret_cast<uword>(patch_target_function), 310 reinterpret_cast<uword>(patch_target_function),
278 Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments)); 311 Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments));
312 #endif
313 } else if (is_auto_scope) {
314 trampoline = StubCode::CallAutoScopeNative_entry()->code();
315 } else {
316 trampoline = StubCode::CallNoScopeNative_entry()->code();
279 } 317 }
280 #endif
281 318
282 CodePatcher::PatchNativeCallAt(caller_frame->pc(), code, 319 CodePatcher::PatchNativeCallAt(caller_frame->pc(), code,
283 patch_target_function, trampoline); 320 patch_target_function, trampoline);
284 321
285 if (FLAG_trace_natives) { 322 if (FLAG_trace_natives) {
286 OS::Print(" -> %p (%s)\n", target_function, 323 OS::Print(" -> %p (%s)\n", target_function,
287 is_bootstrap_native ? "bootstrap" : "non-bootstrap"); 324 is_bootstrap_native ? "bootstrap" : "non-bootstrap");
288 } 325 }
289 } 326 }
290 VERIFY_ON_TRANSITION; 327 VERIFY_ON_TRANSITION;
291 328
292 // Tail-call resolved target. 329 // Tail-call resolved target.
293 if (call_through_wrapper) { 330 if (is_bootstrap_native) {
331 target_function(arguments);
332 } else if (is_auto_scope) {
294 // Because this call is within a compilation unit, Clang doesn't respect 333 // Because this call is within a compilation unit, Clang doesn't respect
295 // the ABI alignment here. 334 // the ABI alignment here.
296 NativeEntry::NativeCallWrapperNoStackCheck( 335 NativeEntry::AutoScopeNativeCallWrapperNoStackCheck(
297 args, reinterpret_cast<Dart_NativeFunction>(target_function)); 336 args, reinterpret_cast<Dart_NativeFunction>(target_function));
298 } else { 337 } else {
299 target_function(arguments); 338 // Because this call is within a compilation unit, Clang doesn't respect
339 // the ABI alignment here.
340 NativeEntry::NoScopeNativeCallWrapperNoStackCheck(
341 args, reinterpret_cast<Dart_NativeFunction>(target_function));
300 } 342 }
301 } 343 }
302 #endif // !defined(TARGET_ARCH_DBC) 344 #endif // !defined(TARGET_ARCH_DBC)
303 345
304 346
305 } // namespace dart 347 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698