| OLD | NEW |
| 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 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 VERIFY_ON_TRANSITION; | 177 VERIFY_ON_TRANSITION; |
| 178 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 178 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
| 179 /* Tell MemorySanitizer 'arguments' is initialized by generated code. */ | 179 /* Tell MemorySanitizer 'arguments' is initialized by generated code. */ |
| 180 MSAN_UNPOISON(arguments, sizeof(*arguments)); | 180 MSAN_UNPOISON(arguments, sizeof(*arguments)); |
| 181 TRACE_NATIVE_CALL("%s", "LinkNative"); | 181 TRACE_NATIVE_CALL("%s", "LinkNative"); |
| 182 | 182 |
| 183 NativeFunction target_function = NULL; | 183 NativeFunction target_function = NULL; |
| 184 bool call_through_wrapper = false; | 184 bool call_through_wrapper = false; |
| 185 #ifdef USING_SIMULATOR | 185 #ifdef USING_SIMULATOR |
| 186 bool is_native_auto_setup_scope = false; | 186 bool is_native_auto_setup_scope = false; |
| 187 intptr_t num_parameters = -1; | |
| 188 #endif | 187 #endif |
| 189 | 188 |
| 190 { | 189 { |
| 191 StackZone zone(arguments->thread()); | 190 StackZone zone(arguments->thread()); |
| 192 | 191 |
| 193 DartFrameIterator iterator; | 192 DartFrameIterator iterator; |
| 194 StackFrame* caller_frame = iterator.NextFrame(); | 193 StackFrame* caller_frame = iterator.NextFrame(); |
| 195 | 194 |
| 196 const Code& code = Code::Handle(caller_frame->LookupDartCode()); | 195 const Code& code = Code::Handle(caller_frame->LookupDartCode()); |
| 197 const Function& func = Function::Handle(code.function()); | 196 const Function& func = Function::Handle(code.function()); |
| 198 #ifdef USING_SIMULATOR | 197 #ifdef USING_SIMULATOR |
| 199 is_native_auto_setup_scope = func.IsNativeAutoSetupScope(); | 198 is_native_auto_setup_scope = func.IsNativeAutoSetupScope(); |
| 200 num_parameters = func.NumParameters(); | |
| 201 #endif | 199 #endif |
| 202 | 200 |
| 203 if (FLAG_trace_natives) { | 201 if (FLAG_trace_natives) { |
| 204 OS::Print("Resolving native target for %s\n", func.ToCString()); | 202 OS::Print("Resolving native target for %s\n", func.ToCString()); |
| 205 } | 203 } |
| 206 | 204 |
| 207 bool is_bootstrap_native = false; | 205 bool is_bootstrap_native = false; |
| 208 target_function = ResolveNativeFunction( | 206 target_function = ResolveNativeFunction( |
| 209 arguments->thread()->isolate(), func, &is_bootstrap_native); | 207 arguments->thread()->isolate(), func, &is_bootstrap_native); |
| 210 ASSERT(target_function != NULL); | 208 ASSERT(target_function != NULL); |
| 211 | 209 |
| 212 #if defined(DEBUG) | 210 #if defined(DEBUG) |
| 213 { | 211 { |
| 214 NativeFunction current_function = NULL; | 212 NativeFunction current_function = NULL; |
| 215 uword current_trampoline = | 213 uword current_trampoline = |
| 216 CodePatcher::GetNativeCallAt(caller_frame->pc(), | 214 CodePatcher::GetNativeCallAt(caller_frame->pc(), |
| 217 code, | 215 code, |
| 218 ¤t_function); | 216 ¤t_function); |
| 219 #if !defined(USING_SIMULATOR) | 217 #if !defined(USING_SIMULATOR) |
| 220 ASSERT(current_function == | 218 ASSERT(current_function == |
| 221 reinterpret_cast<NativeFunction>(LinkNativeCall)); | 219 reinterpret_cast<NativeFunction>(LinkNativeCall)); |
| 222 #else | 220 #else |
| 223 ASSERT(current_function == | 221 ASSERT(current_function == |
| 224 reinterpret_cast<NativeFunction>( | 222 reinterpret_cast<NativeFunction>( |
| 225 Simulator::RedirectExternalReference( | 223 Simulator::RedirectExternalReference( |
| 226 reinterpret_cast<uword>(LinkNativeCall), | 224 reinterpret_cast<uword>(LinkNativeCall), |
| 227 Simulator::kBootstrapNativeCall, | 225 Simulator::kBootstrapNativeCall, |
| 228 func.NumParameters()))); | 226 NativeEntry::kNumArguments))); |
| 229 #endif | 227 #endif |
| 230 ASSERT(current_trampoline == | 228 ASSERT(current_trampoline == |
| 231 StubCode::CallBootstrapCFunction_entry()->EntryPoint()); | 229 StubCode::CallBootstrapCFunction_entry()->EntryPoint()); |
| 232 } | 230 } |
| 233 #endif | 231 #endif |
| 234 | 232 |
| 235 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(func); | 233 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(func); |
| 236 const bool is_leaf_call = | 234 const bool is_leaf_call = |
| 237 (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0; | 235 (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0; |
| 238 | 236 |
| 239 call_through_wrapper = !is_bootstrap_native && !is_leaf_call; | 237 call_through_wrapper = !is_bootstrap_native && !is_leaf_call; |
| 240 | 238 |
| 241 const Code& trampoline = Code::Handle(call_through_wrapper ? | 239 const Code& trampoline = Code::Handle(call_through_wrapper ? |
| 242 StubCode::CallNativeCFunction_entry()->code() : | 240 StubCode::CallNativeCFunction_entry()->code() : |
| 243 StubCode::CallBootstrapCFunction_entry()->code()); | 241 StubCode::CallBootstrapCFunction_entry()->code()); |
| 244 | 242 |
| 245 NativeFunction patch_target_function = target_function; | 243 NativeFunction patch_target_function = target_function; |
| 246 #if defined(USING_SIMULATOR) | 244 #if defined(USING_SIMULATOR) |
| 247 if (!call_through_wrapper || !is_native_auto_setup_scope) { | 245 if (!call_through_wrapper || !is_native_auto_setup_scope) { |
| 248 patch_target_function = reinterpret_cast<NativeFunction>( | 246 patch_target_function = reinterpret_cast<NativeFunction>( |
| 249 Simulator::RedirectExternalReference( | 247 Simulator::RedirectExternalReference( |
| 250 reinterpret_cast<uword>(patch_target_function), | 248 reinterpret_cast<uword>(patch_target_function), |
| 251 Simulator::kBootstrapNativeCall, num_parameters)); | 249 Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments)); |
| 252 } | 250 } |
| 253 #endif | 251 #endif |
| 254 | 252 |
| 255 CodePatcher::PatchNativeCallAt( | 253 CodePatcher::PatchNativeCallAt( |
| 256 caller_frame->pc(), code, patch_target_function, trampoline); | 254 caller_frame->pc(), code, patch_target_function, trampoline); |
| 257 | 255 |
| 258 if (FLAG_trace_natives) { | 256 if (FLAG_trace_natives) { |
| 259 OS::Print(" -> %p (%s, %s)\n", | 257 OS::Print(" -> %p (%s, %s)\n", |
| 260 target_function, | 258 target_function, |
| 261 is_bootstrap_native ? "bootstrap" : "non-bootstrap", | 259 is_bootstrap_native ? "bootstrap" : "non-bootstrap", |
| 262 is_leaf_call ? "leaf" : "non-leaf"); | 260 is_leaf_call ? "leaf" : "non-leaf"); |
| 263 } | 261 } |
| 264 } | 262 } |
| 265 VERIFY_ON_TRANSITION; | 263 VERIFY_ON_TRANSITION; |
| 266 | 264 |
| 267 // Tail-call resolved target. | 265 // Tail-call resolved target. |
| 268 if (call_through_wrapper) { | 266 if (call_through_wrapper) { |
| 269 NativeEntry::NativeCallWrapper( | 267 NativeEntry::NativeCallWrapper( |
| 270 args, reinterpret_cast<Dart_NativeFunction>(target_function)); | 268 args, reinterpret_cast<Dart_NativeFunction>(target_function)); |
| 271 } else { | 269 } else { |
| 272 target_function(arguments); | 270 target_function(arguments); |
| 273 } | 271 } |
| 274 } | 272 } |
| 275 | 273 |
| 276 | 274 |
| 277 } // namespace dart | 275 } // namespace dart |
| OLD | NEW |