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

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

Issue 1294113004: VM: Link native calls lazily. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: added flag Created 5 years, 4 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"
10 #include "vm/code_patcher.h"
9 #include "vm/dart_api_impl.h" 11 #include "vm/dart_api_impl.h"
10 #include "vm/dart_api_state.h" 12 #include "vm/dart_api_state.h"
11 #include "vm/object_store.h" 13 #include "vm/object_store.h"
12 #include "vm/reusable_handles.h" 14 #include "vm/reusable_handles.h"
15 #include "vm/stack_frame.h"
16 #include "vm/symbols.h"
13 #include "vm/tags.h" 17 #include "vm/tags.h"
14 18
15 19
16 namespace dart { 20 namespace dart {
17 21
18 DEFINE_FLAG(bool, trace_natives, false, 22 DEFINE_FLAG(bool, trace_natives, false,
19 "Trace invocation of natives (debug mode only)"); 23 "Trace invocation of natives (debug mode only)");
20 24
21 25
22 static ExternalLabel native_call_label( 26 static ExternalLabel native_call_label(
23 reinterpret_cast<uword>(&NativeEntry::NativeCallWrapper)); 27 reinterpret_cast<uword>(&NativeEntry::NativeCallWrapper));
24 28
25 29
30 static ExternalLabel link_native_call_label(
31 reinterpret_cast<uword>(&NativeEntry::LinkNativeCall));
32
33
26 NativeFunction NativeEntry::ResolveNative(const Library& library, 34 NativeFunction NativeEntry::ResolveNative(const Library& library,
27 const String& function_name, 35 const String& function_name,
28 int number_of_arguments, 36 int number_of_arguments,
29 bool* auto_setup_scope) { 37 bool* auto_setup_scope) {
30 // Now resolve the native function to the corresponding native entrypoint. 38 // Now resolve the native function to the corresponding native entrypoint.
31 if (library.native_entry_resolver() == 0) { 39 if (library.native_entry_resolver() == 0) {
32 // Native methods are not allowed in the library to which this 40 // Native methods are not allowed in the library to which this
33 // class belongs in. 41 // class belongs in.
34 return NULL; 42 return NULL;
35 } 43 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 scope->Reset(thread); // Reset the old scope which we just exited. 124 scope->Reset(thread); // Reset the old scope which we just exited.
117 state->set_reusable_scope(scope); 125 state->set_reusable_scope(scope);
118 } else { 126 } else {
119 ASSERT(state->reusable_scope() != scope); 127 ASSERT(state->reusable_scope() != scope);
120 delete scope; 128 delete scope;
121 } 129 }
122 DEOPTIMIZE_ALOT; 130 DEOPTIMIZE_ALOT;
123 VERIFY_ON_TRANSITION; 131 VERIFY_ON_TRANSITION;
124 } 132 }
125 133
134
135 static bool IsNativeKeyword(const TokenStream::Iterator& it) {
136 return Token::IsIdentifier(it.CurrentTokenKind()) &&
137 (it.CurrentLiteral() == Symbols::Native().raw());
138 }
139
140
141 static NativeFunction ResolveNativeFunction(Isolate *isolate,
142 const Function& func,
143 bool* is_bootstrap_native) {
144 const Script& script = Script::Handle(isolate, func.script());
145 const Class& cls = Class::Handle(isolate, func.Owner());
146 const Library& library = Library::Handle(isolate, cls.library());
147
148 *is_bootstrap_native =
149 Bootstrap::IsBootstapResolver(library.native_entry_resolver());
150
151 TokenStream::Iterator it(TokenStream::Handle(isolate, script.tokens()),
152 func.token_pos());
153
154 const intptr_t end_pos = func.end_token_pos();
155 while (!IsNativeKeyword(it) && it.CurrentPosition() <= end_pos) {
156 it.Advance();
157 }
158 ASSERT(IsNativeKeyword(it));
159 it.Advance();
160 ASSERT(it.CurrentTokenKind() == Token::kSTRING);
161 const String& native_name = String::Handle(it.CurrentLiteral());
162
163 const int num_params = NativeArguments::ParameterCountForResolution(func);
164 bool auto_setup_scope = true;
165 return NativeEntry::ResolveNative(
166 library, native_name, num_params, &auto_setup_scope);
167 }
168
169
170 const ExternalLabel& NativeEntry::LinkNativeCallLabel() {
171 return link_native_call_label;
172 }
173
174
175 void NativeEntry::LinkNativeCall(Dart_NativeArguments args) {
176 CHECK_STACK_ALIGNMENT;
177 VERIFY_ON_TRANSITION;
178 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
179 /* Tell MemorySanitizer 'arguments' is initialized by generated code. */
180 MSAN_UNPOISON(arguments, sizeof(*arguments));
181 TRACE_NATIVE_CALL("%s", "LinkNative");
182
183 NativeFunction target_function = NULL;
184 bool call_through_wrapper = false;
185 bool is_native_auto_setup_scope = false;
rmacnak 2015/08/20 23:48:06 only used behind USING_SIMULATOR
Florian Schneider 2015/08/21 07:58:17 Done.
186 intptr_t num_parameters = -1;
rmacnak 2015/08/20 23:48:06 "
Florian Schneider 2015/08/21 07:58:17 Done.
187
188 {
189 StackZone zone(arguments->thread());
190
191 DartFrameIterator iterator;
192 StackFrame* caller_frame = iterator.NextFrame();
193
194 const Code& code = Code::Handle(caller_frame->LookupDartCode());
195 const Function& func = Function::Handle(code.function());
196 is_native_auto_setup_scope = func.IsNativeAutoSetupScope();
197 num_parameters = func.NumParameters();
198
199 if (FLAG_trace_natives) {
200 OS::Print("Resolving native target for %s\n", func.ToCString());
201 }
202
203 bool is_bootstrap_native = false;
204 target_function = ResolveNativeFunction(
205 arguments->thread()->isolate(), func, &is_bootstrap_native);
206 ASSERT(target_function != NULL);
207
208 #if defined(DEBUG)
209 {
210 NativeFunction current_function = NULL;
211 uword current_trampoline =
212 CodePatcher::GetNativeCallAt(caller_frame->pc(),
213 code,
214 &current_function);
215 #if !defined(USING_SIMULATOR)
216 ASSERT(current_function ==
217 reinterpret_cast<NativeFunction>(LinkNativeCall));
218 #else
219 ASSERT(current_function ==
220 reinterpret_cast<NativeFunction>(
221 Simulator::RedirectExternalReference(
222 reinterpret_cast<uword>(LinkNativeCall),
223 Simulator::kBootstrapNativeCall,
224 func.NumParameters())));
225 #endif
226 ASSERT(current_trampoline ==
227 StubCode::CallBootstrapCFunction_entry()->EntryPoint());
228 }
229 #endif
230
231 const intptr_t argc_tag = NativeArguments::ComputeArgcTag(func);
232 const bool is_leaf_call =
233 (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
234
235 call_through_wrapper = !is_bootstrap_native && !is_leaf_call;
236
237 const Code& trampoline = Code::Handle(call_through_wrapper ?
238 StubCode::CallNativeCFunction_entry()->code() :
239 StubCode::CallBootstrapCFunction_entry()->code());
240
241 NativeFunction patch_target_function = target_function;
242 #if defined(USING_SIMULATOR)
243 if (!call_through_wrapper || !is_native_auto_setup_scope) {
244 patch_target_function = reinterpret_cast<NativeFunction>(
245 Simulator::RedirectExternalReference(
246 reinterpret_cast<uword>(patch_target_function),
247 Simulator::kBootstrapNativeCall, num_parameters));
248 }
249 #endif
250
251 CodePatcher::PatchNativeCallAt(
252 caller_frame->pc(), code, patch_target_function, trampoline);
253
254 if (FLAG_trace_natives) {
255 OS::Print(" -> %p (%s, %s)\n",
256 target_function,
257 is_bootstrap_native ? "bootstrap" : "non-bootstrap",
258 is_leaf_call ? "leaf" : "non-leaf");
259 }
260 }
261 VERIFY_ON_TRANSITION;
262
263 // Tail-call resolved target.
264 if (call_through_wrapper) {
265 NativeEntry::NativeCallWrapper(
266 args, reinterpret_cast<Dart_NativeFunction>(target_function));
267 } else {
268 target_function(arguments);
269 }
270 }
271
272
126 } // namespace dart 273 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/native_entry.h ('k') | runtime/vm/parser.cc » ('j') | runtime/vm/parser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698