Files
sdk/runtime/vm/bootstrap_natives.cc
T
Ryan Macnak 7514ce941e [vm] Assert handles are only allocated when the thread is preventing safepoints.
Threads in the native or blocked states don't prevent safepoints, so they may run concurrently with a safepoint operation like GC. It is not safe for handles to be allocated while the GC is visiting them, so these threads must not allocate handles. Assert only threads in the VM or generated states, which prevent safepoints until they check in, may allocate handles. (Generated code does not allocate handles, but leaf runtime entries remain in the generated state.)

Bug: https://github.com/dart-lang/sdk/issues/34883
Change-Id: I1a211778f7ef96b53a2405f0ee9dde7871b122b6
Reviewed-on: https://dart-review.googlesource.com/c/81540
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
2018-10-31 19:51:52 +00:00

147 lines
5.0 KiB
C++

// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "vm/bootstrap.h"
#include "include/dart_api.h"
#include "vm/bootstrap_natives.h"
#include "vm/dart_api_impl.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/service_isolate.h"
namespace dart {
// Helper macros for declaring and defining native entries.
#define REGISTER_NATIVE_ENTRY(name, count) \
{"" #name, BootstrapNatives::DN_##name, count},
// List all native functions implemented in the vm or core bootstrap dart
// libraries so that we can resolve the native function to it's entry
// point.
static struct NativeEntries {
const char* name_;
Dart_NativeFunction function_;
int argument_count_;
} BootStrapEntries[] = {BOOTSTRAP_NATIVE_LIST(REGISTER_NATIVE_ENTRY)
#if !defined(DART_PRECOMPILED_RUNTIME)
MIRRORS_BOOTSTRAP_NATIVE_LIST(REGISTER_NATIVE_ENTRY)
#endif // !DART_PRECOMPILED_RUNTIME
};
Dart_NativeFunction BootstrapNatives::Lookup(Dart_Handle name,
int argument_count,
bool* auto_setup_scope) {
Thread* thread = Thread::Current();
TransitionNativeToVM transition(thread);
const Object& obj = Object::Handle(thread->zone(), Api::UnwrapHandle(name));
if (!obj.IsString()) {
return NULL;
}
ASSERT(auto_setup_scope);
*auto_setup_scope = false;
const char* function_name = obj.ToCString();
ASSERT(function_name != NULL);
int num_entries = sizeof(BootStrapEntries) / sizeof(struct NativeEntries);
for (int i = 0; i < num_entries; i++) {
struct NativeEntries* entry = &(BootStrapEntries[i]);
if ((strcmp(function_name, entry->name_) == 0) &&
(entry->argument_count_ == argument_count)) {
return reinterpret_cast<Dart_NativeFunction>(entry->function_);
}
}
return NULL;
}
const uint8_t* BootstrapNatives::Symbol(Dart_NativeFunction* nf) {
int num_entries = sizeof(BootStrapEntries) / sizeof(struct NativeEntries);
for (int i = 0; i < num_entries; i++) {
struct NativeEntries* entry = &(BootStrapEntries[i]);
if (reinterpret_cast<Dart_NativeFunction*>(entry->function_) == nf) {
return reinterpret_cast<const uint8_t*>(entry->name_);
}
}
return NULL;
}
void Bootstrap::SetupNativeResolver() {
Library& library = Library::Handle();
Dart_NativeEntryResolver resolver =
reinterpret_cast<Dart_NativeEntryResolver>(BootstrapNatives::Lookup);
Dart_NativeEntrySymbol symbol_resolver =
reinterpret_cast<Dart_NativeEntrySymbol>(BootstrapNatives::Symbol);
library = Library::AsyncLibrary();
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
library.set_native_entry_symbol_resolver(symbol_resolver);
library = Library::CollectionLibrary();
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
library.set_native_entry_symbol_resolver(symbol_resolver);
library = Library::ConvertLibrary();
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
library.set_native_entry_symbol_resolver(symbol_resolver);
library = Library::CoreLibrary();
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
library.set_native_entry_symbol_resolver(symbol_resolver);
library = Library::DeveloperLibrary();
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
library.set_native_entry_symbol_resolver(symbol_resolver);
library = Library::InternalLibrary();
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
library.set_native_entry_symbol_resolver(symbol_resolver);
library = Library::IsolateLibrary();
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
library.set_native_entry_symbol_resolver(symbol_resolver);
library = Library::MathLibrary();
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
library.set_native_entry_symbol_resolver(symbol_resolver);
#if !defined(DART_PRECOMPILED_RUNTIME)
library = Library::MirrorsLibrary();
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
library.set_native_entry_symbol_resolver(symbol_resolver);
#endif
library = Library::ProfilerLibrary();
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
library.set_native_entry_symbol_resolver(symbol_resolver);
library = Library::TypedDataLibrary();
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
library.set_native_entry_symbol_resolver(symbol_resolver);
library = Library::VMServiceLibrary();
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
library.set_native_entry_symbol_resolver(symbol_resolver);
}
bool Bootstrap::IsBootstrapResolver(Dart_NativeEntryResolver resolver) {
return (resolver ==
reinterpret_cast<Dart_NativeEntryResolver>(BootstrapNatives::Lookup));
}
} // namespace dart