Commit 5c9b30ae authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[api] Split isolate allocation and initialization

At the moment, the isolate is allocated and initialized in a single
step. This has the downside that the platform cannot register the
isolate before the isolate gets initialized, and therefore the platform
is not available for the isolate during initialization. With this CL we
register the uninitialized isolate on the platform and initialize the
isolate after that.

This change is needed to allow the creation of task runners already
during the initialization of the isolate.

The related chromium CL: https://crrev.com/c/1015020

R=yangguo@chromium.org

Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: I52e89388a757f2693d1a800e7aa7701aa0080795
Reviewed-on: https://chromium-review.googlesource.com/1014044Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52731}
parent 62b22fbd
......@@ -7121,6 +7121,22 @@ class V8_EXPORT Isolate {
typedef void (*UseCounterCallback)(Isolate* isolate,
UseCounterFeature feature);
/**
* Allocates a new isolate but does not initialize it. Does not change the
* currently entered isolate. Initialize the isolate by calling
* Isolate::Initialize().
*
* When an isolate is no longer used its resources should be freed
* by calling Dispose(). Using the delete operator is not allowed.
*
* V8::Initialize() must have run prior to this.
*/
static Isolate* Allocate();
/**
* Initialize an Isolate previously allocated by Isolate::Allocate().
*/
static void Initialize(Isolate* isolate, const CreateParams& params);
/**
* Creates a new isolate. Does not change the currently entered
......@@ -8178,6 +8194,18 @@ class V8_EXPORT SnapshotCreator {
public:
enum class FunctionCodeHandling { kClear, kKeep };
/**
* Initialize and enter an isolate, and set it up for serialization.
* The isolate is either created from scratch or from an existing snapshot.
* The caller keeps ownership of the argument snapshot.
* \param existing_blob existing snapshot from which to create this one.
* \param external_references a null-terminated array of external references
* that must be equivalent to CreateParams::external_references.
*/
SnapshotCreator(Isolate* isolate,
const intptr_t* external_references = nullptr,
StartupData* existing_blob = nullptr);
/**
* Create and enter an isolate, and set it up for serialization.
* The isolate is either created from scratch or from an existing snapshot.
......
......@@ -543,14 +543,15 @@ struct SnapshotCreatorData {
} // namespace
SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
SnapshotCreator::SnapshotCreator(Isolate* isolate,
const intptr_t* external_references,
StartupData* existing_snapshot) {
i::Isolate* internal_isolate = new i::Isolate(true);
Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
SnapshotCreatorData* data = new SnapshotCreatorData(isolate);
data->isolate_ = isolate;
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
internal_isolate->set_array_buffer_allocator(&data->allocator_);
internal_isolate->set_api_external_references(external_references);
internal_isolate->enable_serializer();
isolate->Enter();
const StartupData* blob = existing_snapshot
? existing_snapshot
......@@ -564,6 +565,11 @@ SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
data_ = data;
}
SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
StartupData* existing_snapshot)
: SnapshotCreator(reinterpret_cast<Isolate*>(new i::Isolate()),
external_references, existing_snapshot) {}
SnapshotCreator::~SnapshotCreator() {
SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
DCHECK(data->created_);
......@@ -8150,22 +8156,22 @@ Isolate* Isolate::GetCurrent() {
return reinterpret_cast<Isolate*>(isolate);
}
Isolate* Isolate::New(const Isolate::CreateParams& params) {
i::Isolate* isolate = new i::Isolate(false);
return IsolateNewImpl(isolate, params);
// static
Isolate* Isolate::Allocate() {
return reinterpret_cast<Isolate*>(new i::Isolate());
}
// static
// This is separate so that tests can provide a different |isolate|.
Isolate* IsolateNewImpl(internal::Isolate* isolate,
const v8::Isolate::CreateParams& params) {
Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
void Isolate::Initialize(Isolate* isolate,
const v8::Isolate::CreateParams& params) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
CHECK_NOT_NULL(params.array_buffer_allocator);
isolate->set_array_buffer_allocator(params.array_buffer_allocator);
i_isolate->set_array_buffer_allocator(params.array_buffer_allocator);
if (params.snapshot_blob != nullptr) {
isolate->set_snapshot_blob(params.snapshot_blob);
i_isolate->set_snapshot_blob(params.snapshot_blob);
} else {
isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
i_isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
}
if (params.entry_hook) {
#ifdef V8_USE_SNAPSHOT
......@@ -8174,7 +8180,7 @@ Isolate* IsolateNewImpl(internal::Isolate* isolate,
false, "v8::Isolate::New",
"Setting a FunctionEntryHook is only supported in no-snapshot builds.");
#endif
isolate->set_function_entry_hook(params.entry_hook);
i_isolate->set_function_entry_hook(params.entry_hook);
}
auto code_event_handler = params.code_event_handler;
#ifdef ENABLE_GDB_JIT_INTERFACE
......@@ -8183,44 +8189,48 @@ Isolate* IsolateNewImpl(internal::Isolate* isolate,
}
#endif // ENABLE_GDB_JIT_INTERFACE
if (code_event_handler) {
isolate->InitializeLoggingAndCounters();
isolate->logger()->SetCodeEventHandler(kJitCodeEventDefault,
code_event_handler);
i_isolate->InitializeLoggingAndCounters();
i_isolate->logger()->SetCodeEventHandler(kJitCodeEventDefault,
code_event_handler);
}
if (params.counter_lookup_callback) {
v8_isolate->SetCounterFunction(params.counter_lookup_callback);
isolate->SetCounterFunction(params.counter_lookup_callback);
}
if (params.create_histogram_callback) {
v8_isolate->SetCreateHistogramFunction(params.create_histogram_callback);
isolate->SetCreateHistogramFunction(params.create_histogram_callback);
}
if (params.add_histogram_sample_callback) {
v8_isolate->SetAddHistogramSampleFunction(
isolate->SetAddHistogramSampleFunction(
params.add_histogram_sample_callback);
}
isolate->set_api_external_references(params.external_references);
isolate->set_allow_atomics_wait(params.allow_atomics_wait);
i_isolate->set_api_external_references(params.external_references);
i_isolate->set_allow_atomics_wait(params.allow_atomics_wait);
SetResourceConstraints(isolate, params.constraints);
SetResourceConstraints(i_isolate, params.constraints);
// TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
Isolate::Scope isolate_scope(v8_isolate);
if (params.entry_hook || !i::Snapshot::Initialize(isolate)) {
Isolate::Scope isolate_scope(isolate);
if (params.entry_hook || !i::Snapshot::Initialize(i_isolate)) {
// If snapshot data was provided and we failed to deserialize it must
// have been corrupted.
CHECK_NULL(isolate->snapshot_blob());
CHECK_NULL(i_isolate->snapshot_blob());
base::ElapsedTimer timer;
if (i::FLAG_profile_deserialization) timer.Start();
isolate->Init(nullptr);
i_isolate->Init(nullptr);
if (i::FLAG_profile_deserialization) {
double ms = timer.Elapsed().InMillisecondsF();
i::PrintF("[Initializing isolate from scratch took %0.3f ms]\n", ms);
}
}
return v8_isolate;
}
Isolate* Isolate::New(const Isolate::CreateParams& params) {
Isolate* isolate = Allocate();
Initialize(isolate, params);
return isolate;
}
void Isolate::Dispose() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
......
......@@ -376,9 +376,6 @@ OPEN_HANDLE_LIST(MAKE_OPEN_HANDLE)
#undef MAKE_OPEN_HANDLE
#undef OPEN_HANDLE_LIST
extern Isolate* IsolateNewImpl(internal::Isolate* isolate,
const Isolate::CreateParams& params);
namespace internal {
class V8_EXPORT_PRIVATE DeferredHandles {
......
......@@ -2503,7 +2503,7 @@ class VerboseAccountingAllocator : public AccountingAllocator {
base::AtomicNumber<size_t> Isolate::non_disposed_isolates_;
#endif // DEBUG
Isolate::Isolate(bool enable_serializer)
Isolate::Isolate()
: embedder_data_(),
entry_stack_(nullptr),
stack_trace_nesting_level_(0),
......@@ -2543,7 +2543,7 @@ Isolate::Isolate(bool enable_serializer)
promise_hook_or_debug_is_active_(false),
promise_hook_(nullptr),
load_start_time_ms_(0),
serializer_enabled_(enable_serializer),
serializer_enabled_(false),
has_fatal_error_(false),
initialized_from_snapshot_(false),
is_tail_call_elimination_enabled_(true),
......
......@@ -1001,6 +1001,9 @@ class Isolate : private HiddenFactory {
}
bool serializer_enabled() const { return serializer_enabled_; }
void enable_serializer() { serializer_enabled_ = true; }
bool snapshot_available() const {
return snapshot_blob_ != nullptr && snapshot_blob_->raw_size != 0;
}
......@@ -1382,7 +1385,7 @@ class Isolate : private HiddenFactory {
void SetIdle(bool is_idle);
protected:
explicit Isolate(bool enable_serializer);
Isolate();
bool IsArrayOrObjectOrStringPrototype(Object* object);
private:
......
......@@ -91,9 +91,12 @@ class TestIsolate : public Isolate {
bool create_heap_objects = params.snapshot_blob == nullptr;
isolate->setup_delegate_ =
new SetupIsolateDelegateForTests(create_heap_objects);
return v8::IsolateNewImpl(isolate, params);
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
v8::Isolate::Initialize(v8_isolate, params);
return v8_isolate;
}
explicit TestIsolate(bool enable_serializer) : Isolate(enable_serializer) {
explicit TestIsolate(bool with_serializer) : Isolate() {
if (with_serializer) enable_serializer();
set_array_buffer_allocator(CcTest::array_buffer_allocator());
}
void SetDeserializeFromSnapshot() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment