[isolate] Introduce SaveAndSwitchContext
The most common use of {SaveContext} is to allocate this object, then immediately set the context of the isolate to another Context. Thus introduce a second class called "SaveAndSwitchContext" which implements exactly that. R=mstarzinger@chromium.org Bug: v8:8562 Change-Id: I2fca1eadd909a7afe035316ded934624273f2e21 Reviewed-on: https://chromium-review.googlesource.com/c/1448319 Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#59323}
This commit is contained in:
parent
40633b4f48
commit
bb2ee0468c
@ -5177,8 +5177,7 @@ bool Bootstrapper::InstallExtensions(Handle<Context> native_context,
|
||||
// Don't install extensions into the snapshot.
|
||||
if (isolate_->serializer_enabled()) return true;
|
||||
BootstrapperActive active(this);
|
||||
SaveContext saved_context(isolate_);
|
||||
isolate_->set_context(*native_context);
|
||||
SaveAndSwitchContext saved_context(isolate_, *native_context);
|
||||
return Genesis::InstallExtensions(isolate_, native_context, extensions) &&
|
||||
Genesis::InstallSpecialObjects(isolate_, native_context);
|
||||
}
|
||||
|
@ -2996,8 +2996,7 @@ bool ProcessMessages(
|
||||
const std::function<platform::MessageLoopBehavior()>& behavior) {
|
||||
while (true) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
i::SaveContext saved_context(i_isolate);
|
||||
i_isolate->set_context(i::Context());
|
||||
i::SaveAndSwitchContext saved_context(i_isolate, i::Context());
|
||||
SealHandleScope shs(isolate);
|
||||
while (v8::platform::PumpMessageLoop(g_default_platform, isolate,
|
||||
behavior())) {
|
||||
|
@ -195,8 +195,7 @@ V8_WARN_UNUSED_RESULT MaybeHandle<Object> Invoke(Isolate* isolate,
|
||||
if ((!params.is_construct || function->IsConstructor()) &&
|
||||
function->shared()->IsApiFunction() &&
|
||||
!function->shared()->BreakAtEntry()) {
|
||||
SaveContext save(isolate);
|
||||
isolate->set_context(function->context());
|
||||
SaveAndSwitchContext save(isolate, function->context());
|
||||
DCHECK(function->context()->global_object()->IsJSGlobalObject());
|
||||
|
||||
Handle<Object> receiver = params.is_construct
|
||||
|
@ -3485,8 +3485,7 @@ MaybeHandle<JSBoundFunction> Factory::NewJSBoundFunction(
|
||||
isolate(), prototype,
|
||||
JSReceiver::GetPrototype(isolate(), target_function), JSBoundFunction);
|
||||
|
||||
SaveContext save(isolate());
|
||||
isolate()->set_context(*target_function->GetCreationContext());
|
||||
SaveAndSwitchContext save(isolate(), *target_function->GetCreationContext());
|
||||
|
||||
// Create the [[BoundArguments]] for the result.
|
||||
Handle<FixedArray> bound_arguments;
|
||||
|
@ -958,8 +958,7 @@ Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(
|
||||
#ifdef DEBUG
|
||||
// Unoptimized compilation should be context-independent. Verify that we don't
|
||||
// access the native context by nulling it out during finalization.
|
||||
SaveContext save(isolate);
|
||||
isolate->set_context(Context());
|
||||
SaveAndSwitchContext save(isolate, Context());
|
||||
#endif
|
||||
|
||||
AllocateDeferredConstants(isolate, script);
|
||||
|
@ -4551,6 +4551,12 @@ bool SaveContext::IsBelowFrame(StandardFrame* frame) {
|
||||
return (c_entry_fp_ == 0) || (c_entry_fp_ > frame->sp());
|
||||
}
|
||||
|
||||
SaveAndSwitchContext::SaveAndSwitchContext(Isolate* isolate,
|
||||
Context new_context)
|
||||
: SaveContext(isolate) {
|
||||
isolate->set_context(new_context);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
AssertNoContextChange::AssertNoContextChange(Isolate* isolate)
|
||||
: isolate_(isolate), context_(isolate->context(), isolate) {}
|
||||
|
@ -90,7 +90,6 @@ class PromiseOnStack;
|
||||
class RegExpStack;
|
||||
class RootVisitor;
|
||||
class RuntimeProfiler;
|
||||
class SaveContext;
|
||||
class SetupIsolateDelegate;
|
||||
class Simulator;
|
||||
class StartupDeserializer;
|
||||
@ -1943,10 +1942,12 @@ class PromiseOnStack {
|
||||
PromiseOnStack* prev_;
|
||||
};
|
||||
|
||||
|
||||
// SaveContext scopes save the current context on the Isolate on creation, and
|
||||
// restore it on destruction.
|
||||
class V8_EXPORT_PRIVATE SaveContext {
|
||||
public:
|
||||
explicit SaveContext(Isolate* isolate);
|
||||
|
||||
~SaveContext();
|
||||
|
||||
Handle<Context> context() { return context_; }
|
||||
@ -1960,6 +1961,13 @@ class V8_EXPORT_PRIVATE SaveContext {
|
||||
Address c_entry_fp_;
|
||||
};
|
||||
|
||||
// Like SaveContext, but also switches the Context to a new one in the
|
||||
// constructor.
|
||||
class V8_EXPORT_PRIVATE SaveAndSwitchContext : public SaveContext {
|
||||
public:
|
||||
SaveAndSwitchContext(Isolate* isolate, Context new_context);
|
||||
};
|
||||
|
||||
class AssertNoContextChange {
|
||||
#ifdef DEBUG
|
||||
public:
|
||||
|
@ -1417,8 +1417,7 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
|
||||
// Regular accessor.
|
||||
Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate);
|
||||
if (getter->IsFunctionTemplateInfo()) {
|
||||
SaveContext save(isolate);
|
||||
isolate->set_context(*holder->GetCreationContext());
|
||||
SaveAndSwitchContext save(isolate, *holder->GetCreationContext());
|
||||
return Builtins::InvokeApiFunction(
|
||||
isolate, false, Handle<FunctionTemplateInfo>::cast(getter), receiver, 0,
|
||||
nullptr, isolate->factory()->undefined_value());
|
||||
@ -1523,8 +1522,7 @@ Maybe<bool> Object::SetPropertyWithAccessor(
|
||||
// Regular accessor.
|
||||
Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
|
||||
if (setter->IsFunctionTemplateInfo()) {
|
||||
SaveContext save(isolate);
|
||||
isolate->set_context(*holder->GetCreationContext());
|
||||
SaveAndSwitchContext save(isolate, *holder->GetCreationContext());
|
||||
Handle<Object> argv[] = {value};
|
||||
RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, Builtins::InvokeApiFunction(
|
||||
|
@ -978,8 +978,8 @@ class AsyncCompileJob::CompilationStateCallback {
|
||||
job->foreground_task_runner_->PostTask(
|
||||
MakeCancelableTask(job->isolate_, [job] {
|
||||
HandleScope scope(job->isolate_);
|
||||
SaveContext saved_context(job->isolate_);
|
||||
job->isolate_->set_context(*job->native_context_);
|
||||
SaveAndSwitchContext saved_context(job->isolate_,
|
||||
*job->native_context_);
|
||||
job->FinishCompile();
|
||||
}));
|
||||
}
|
||||
@ -1000,8 +1000,8 @@ class AsyncCompileJob::CompilationStateCallback {
|
||||
job->foreground_task_runner_->PostTask(
|
||||
MakeCancelableTask(job->isolate_, [job] {
|
||||
HandleScope scope(job->isolate_);
|
||||
SaveContext saved_context(job->isolate_);
|
||||
job->isolate_->set_context(*job->native_context_);
|
||||
SaveAndSwitchContext saved_context(job->isolate_,
|
||||
*job->native_context_);
|
||||
WasmError error = Impl(job->native_module_->compilation_state())
|
||||
->GetCompileError();
|
||||
return job->AsyncCompileFailed(error);
|
||||
@ -1035,8 +1035,7 @@ class AsyncCompileJob::CompileStep {
|
||||
void Run(AsyncCompileJob* job, bool on_foreground) {
|
||||
if (on_foreground) {
|
||||
HandleScope scope(job->isolate_);
|
||||
SaveContext saved_context(job->isolate_);
|
||||
job->isolate_->set_context(*job->native_context_);
|
||||
SaveAndSwitchContext saved_context(job->isolate_, *job->native_context_);
|
||||
RunInForeground(job);
|
||||
} else {
|
||||
RunInBackground(job);
|
||||
@ -1419,8 +1418,7 @@ void AsyncStreamingProcessor::OnFinishedStream(OwnedVector<uint8_t> bytes) {
|
||||
// CreateNativeModule, PrepareRuntimeObjects and FinishCompile as this is a
|
||||
// callback from the embedder.
|
||||
HandleScope scope(job_->isolate_);
|
||||
SaveContext saved_context(job_->isolate_);
|
||||
job_->isolate_->set_context(*job_->native_context_);
|
||||
SaveAndSwitchContext saved_context(job_->isolate_, *job_->native_context_);
|
||||
|
||||
bool needs_finish = job_->DecrementAndCheckFinisherCount();
|
||||
if (job_->native_module_ == nullptr) {
|
||||
@ -1452,8 +1450,7 @@ bool AsyncStreamingProcessor::Deserialize(Vector<const uint8_t> module_bytes,
|
||||
// DeserializeNativeModule and FinishCompile assume that they are executed in
|
||||
// a HandleScope, and that a context is set on the isolate.
|
||||
HandleScope scope(job_->isolate_);
|
||||
SaveContext saved_context(job_->isolate_);
|
||||
job_->isolate_->set_context(*job_->native_context_);
|
||||
SaveAndSwitchContext saved_context(job_->isolate_, *job_->native_context_);
|
||||
|
||||
MaybeHandle<WasmModuleObject> result =
|
||||
DeserializeNativeModule(job_->isolate_, module_bytes, wire_bytes);
|
||||
|
Loading…
Reference in New Issue
Block a user