Commit bb2ee046 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[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/1448319Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59323}
parent 40633b4f
......@@ -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);
......
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