| Index: runtime/vm/native_entry.cc
|
| diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc
|
| index 7e1655e5867e358be33009a579ac6e5141b94ddd..0420b4ac98ce7e77835f54ca04c9184404288393 100644
|
| --- a/runtime/vm/native_entry.cc
|
| +++ b/runtime/vm/native_entry.cc
|
| @@ -91,17 +91,6 @@ const uint8_t* NativeEntry::ResolveSymbol(uword pc) {
|
| }
|
|
|
|
|
| -uword NativeEntry::NativeCallWrapperEntry() {
|
| - uword entry = reinterpret_cast<uword>(NativeEntry::NativeCallWrapper);
|
| -#if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC)
|
| - // DBC does not use redirections unlike other simulators.
|
| - entry = Simulator::RedirectExternalReference(
|
| - entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments);
|
| -#endif
|
| - return entry;
|
| -}
|
| -
|
| -
|
| bool NativeEntry::ReturnValueIsError(NativeArguments* arguments) {
|
| RawObject* retval = arguments->ReturnValue();
|
| return (retval->IsHeapObject() &&
|
| @@ -121,28 +110,74 @@ void NativeEntry::PropagateErrors(NativeArguments* arguments) {
|
| }
|
|
|
|
|
| -void NativeEntry::NativeCallWrapper(Dart_NativeArguments args,
|
| - Dart_NativeFunction func) {
|
| +uword NativeEntry::NoScopeNativeCallWrapperEntry() {
|
| + uword entry = reinterpret_cast<uword>(NativeEntry::NoScopeNativeCallWrapper);
|
| +#if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC)
|
| + // DBC does not use redirections unlike other simulators.
|
| + entry = Simulator::RedirectExternalReference(
|
| + entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments);
|
| +#endif
|
| + return entry;
|
| +}
|
| +
|
| +
|
| +void NativeEntry::NoScopeNativeCallWrapper(Dart_NativeArguments args,
|
| + Dart_NativeFunction func) {
|
| CHECK_STACK_ALIGNMENT;
|
| - NativeCallWrapperNoStackCheck(args, func);
|
| + NoScopeNativeCallWrapperNoStackCheck(args, func);
|
| }
|
|
|
|
|
| -void NativeEntry::NativeCallWrapperNoStackCheck(Dart_NativeArguments args,
|
| - Dart_NativeFunction func) {
|
| +void NativeEntry::NoScopeNativeCallWrapperNoStackCheck(
|
| + Dart_NativeArguments args,
|
| + Dart_NativeFunction func) {
|
| VERIFY_ON_TRANSITION;
|
| NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
|
| /* Tell MemorySanitizer 'arguments' is initialized by generated code. */
|
| MSAN_UNPOISON(arguments, sizeof(*arguments));
|
| Thread* thread = arguments->thread();
|
| ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
|
| - if (!arguments->IsNativeAutoSetupScope()) {
|
| + {
|
| TransitionGeneratedToNative transition(thread);
|
| func(args);
|
| if (ReturnValueIsError(arguments)) {
|
| PropagateErrors(arguments);
|
| }
|
| - } else {
|
| + }
|
| + ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
|
| + VERIFY_ON_TRANSITION;
|
| +}
|
| +
|
| +
|
| +uword NativeEntry::AutoScopeNativeCallWrapperEntry() {
|
| + uword entry =
|
| + reinterpret_cast<uword>(NativeEntry::AutoScopeNativeCallWrapper);
|
| +#if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC)
|
| + // DBC does not use redirections unlike other simulators.
|
| + entry = Simulator::RedirectExternalReference(
|
| + entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments);
|
| +#endif
|
| + return entry;
|
| +}
|
| +
|
| +
|
| +void NativeEntry::AutoScopeNativeCallWrapper(Dart_NativeArguments args,
|
| + Dart_NativeFunction func) {
|
| + CHECK_STACK_ALIGNMENT;
|
| + AutoScopeNativeCallWrapperNoStackCheck(args, func);
|
| +}
|
| +
|
| +
|
| +void NativeEntry::AutoScopeNativeCallWrapperNoStackCheck(
|
| + Dart_NativeArguments args,
|
| + Dart_NativeFunction func) {
|
| + VERIFY_ON_TRANSITION;
|
| + NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
|
| + /* Tell MemorySanitizer 'arguments' is initialized by generated code. */
|
| + MSAN_UNPOISON(arguments, sizeof(*arguments));
|
| + Thread* thread = arguments->thread();
|
| + ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
|
| + {
|
| Isolate* isolate = thread->isolate();
|
| ApiState* state = isolate->api_state();
|
| ASSERT(state != NULL);
|
| @@ -185,7 +220,8 @@ void NativeEntry::NativeCallWrapperNoStackCheck(Dart_NativeArguments args,
|
| #if !defined(TARGET_ARCH_DBC)
|
| static NativeFunction ResolveNativeFunction(Zone* zone,
|
| const Function& func,
|
| - bool* is_bootstrap_native) {
|
| + bool* is_bootstrap_native,
|
| + bool* is_auto_scope) {
|
| const Class& cls = Class::Handle(zone, func.Owner());
|
| const Library& library = Library::Handle(zone, cls.library());
|
|
|
| @@ -196,9 +232,8 @@ static NativeFunction ResolveNativeFunction(Zone* zone,
|
| ASSERT(!native_name.IsNull());
|
|
|
| const int num_params = NativeArguments::ParameterCountForResolution(func);
|
| - bool auto_setup_scope = true;
|
| return NativeEntry::ResolveNative(library, native_name, num_params,
|
| - &auto_setup_scope);
|
| + is_auto_scope);
|
| }
|
|
|
|
|
| @@ -221,33 +256,35 @@ void NativeEntry::LinkNativeCall(Dart_NativeArguments args) {
|
| TRACE_NATIVE_CALL("%s", "LinkNative");
|
|
|
| NativeFunction target_function = NULL;
|
| - bool call_through_wrapper = false;
|
| + bool is_bootstrap_native = false;
|
| + bool is_auto_scope = true;
|
|
|
| {
|
| TransitionGeneratedToVM transition(arguments->thread());
|
| - StackZone zone(arguments->thread());
|
| + StackZone stack_zone(arguments->thread());
|
| + Zone* zone = stack_zone.GetZone();
|
|
|
| DartFrameIterator iterator;
|
| StackFrame* caller_frame = iterator.NextFrame();
|
|
|
| - const Code& code = Code::Handle(caller_frame->LookupDartCode());
|
| - const Function& func = Function::Handle(code.function());
|
| + const Code& code = Code::Handle(zone, caller_frame->LookupDartCode());
|
| + const Function& func = Function::Handle(zone, code.function());
|
|
|
| if (FLAG_trace_natives) {
|
| OS::Print("Resolving native target for %s\n", func.ToCString());
|
| }
|
|
|
| - bool is_bootstrap_native = false;
|
| - target_function = ResolveNativeFunction(arguments->thread()->zone(), func,
|
| - &is_bootstrap_native);
|
| + target_function =
|
| + ResolveNativeFunction(arguments->thread()->zone(), func,
|
| + &is_bootstrap_native, &is_auto_scope);
|
| ASSERT(target_function != NULL);
|
|
|
| #if defined(DEBUG)
|
| {
|
| NativeFunction current_function = NULL;
|
| const Code& current_trampoline =
|
| - Code::Handle(CodePatcher::GetNativeCallAt(caller_frame->pc(), code,
|
| - ¤t_function));
|
| + Code::Handle(zone, CodePatcher::GetNativeCallAt(
|
| + caller_frame->pc(), code, ¤t_function));
|
| #if !defined(USING_SIMULATOR)
|
| ASSERT(current_function ==
|
| reinterpret_cast<NativeFunction>(LinkNativeCall));
|
| @@ -259,25 +296,25 @@ void NativeEntry::LinkNativeCall(Dart_NativeArguments args) {
|
| Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments)));
|
| #endif
|
| ASSERT(current_trampoline.raw() ==
|
| - StubCode::CallBootstrapCFunction_entry()->code());
|
| + StubCode::CallBootstrapNative_entry()->code());
|
| }
|
| #endif
|
|
|
| - call_through_wrapper = !is_bootstrap_native;
|
| - const Code& trampoline =
|
| - Code::Handle(call_through_wrapper
|
| - ? StubCode::CallNativeCFunction_entry()->code()
|
| - : StubCode::CallBootstrapCFunction_entry()->code());
|
| -
|
| NativeFunction patch_target_function = target_function;
|
| + Code& trampoline = Code::Handle(zone);
|
| + if (is_bootstrap_native) {
|
| + trampoline = StubCode::CallBootstrapNative_entry()->code();
|
| #if defined(USING_SIMULATOR)
|
| - if (!call_through_wrapper) {
|
| patch_target_function =
|
| reinterpret_cast<NativeFunction>(Simulator::RedirectExternalReference(
|
| reinterpret_cast<uword>(patch_target_function),
|
| Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments));
|
| - }
|
| #endif
|
| + } else if (is_auto_scope) {
|
| + trampoline = StubCode::CallAutoScopeNative_entry()->code();
|
| + } else {
|
| + trampoline = StubCode::CallNoScopeNative_entry()->code();
|
| + }
|
|
|
| CodePatcher::PatchNativeCallAt(caller_frame->pc(), code,
|
| patch_target_function, trampoline);
|
| @@ -290,13 +327,18 @@ void NativeEntry::LinkNativeCall(Dart_NativeArguments args) {
|
| VERIFY_ON_TRANSITION;
|
|
|
| // Tail-call resolved target.
|
| - if (call_through_wrapper) {
|
| + if (is_bootstrap_native) {
|
| + target_function(arguments);
|
| + } else if (is_auto_scope) {
|
| // Because this call is within a compilation unit, Clang doesn't respect
|
| // the ABI alignment here.
|
| - NativeEntry::NativeCallWrapperNoStackCheck(
|
| + NativeEntry::AutoScopeNativeCallWrapperNoStackCheck(
|
| args, reinterpret_cast<Dart_NativeFunction>(target_function));
|
| } else {
|
| - target_function(arguments);
|
| + // Because this call is within a compilation unit, Clang doesn't respect
|
| + // the ABI alignment here.
|
| + NativeEntry::NoScopeNativeCallWrapperNoStackCheck(
|
| + args, reinterpret_cast<Dart_NativeFunction>(target_function));
|
| }
|
| }
|
| #endif // !defined(TARGET_ARCH_DBC)
|
|
|