[protectors] Create protectors class

Adds a simple static class to manage fast path protectors, thereby
eventually allowing us to remove a bunch of boilerplate from isolate.

Bug: v8:9463
Change-Id: I99306e5c914c16045d0b891bdc3c62cfd98fddfc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1774187
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Joshua Litt <joshualitt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63450}
This commit is contained in:
Joshua Litt 2019-08-29 05:11:14 -07:00 committed by Commit Bot
parent 352a154e88
commit af31c024ff
13 changed files with 128 additions and 36 deletions

View File

@ -2226,6 +2226,9 @@ v8_source_set("v8_base_without_compiler") {
"src/execution/messages.h",
"src/execution/microtask-queue.cc",
"src/execution/microtask-queue.h",
"src/execution/protectors-inl.h",
"src/execution/protectors.cc",
"src/execution/protectors.h",
"src/execution/runtime-profiler.cc",
"src/execution/runtime-profiler.h",
"src/execution/simulator-base.cc",

View File

@ -10,6 +10,7 @@
#include "src/builtins/growable-fixed-array-gen.h"
#include "src/codegen/code-factory.h"
#include "src/codegen/code-stub-assembler.h"
#include "src/execution/protectors.h"
#include "src/heap/factory-inl.h"
#include "src/logging/counters.h"
#include "src/objects/js-regexp-string-iterator.h"

View File

@ -6215,8 +6215,7 @@ TNode<BoolT> CodeStubAssembler::IsTypedArraySpeciesProtectorCellInvalid() {
}
TNode<BoolT> CodeStubAssembler::IsRegExpSpeciesProtectorCellInvalid(
TNode<Context> native_context) {
CSA_ASSERT(this, IsNativeContext(native_context));
TNode<NativeContext> native_context) {
TNode<PropertyCell> cell = CAST(LoadContextElement(
native_context, Context::REGEXP_SPECIES_PROTECTOR_INDEX));
TNode<Object> cell_value = LoadObjectField(cell, PropertyCell::kValueOffset);

View File

@ -2471,7 +2471,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsArraySpeciesProtectorCellInvalid();
TNode<BoolT> IsTypedArraySpeciesProtectorCellInvalid();
TNode<BoolT> IsRegExpSpeciesProtectorCellInvalid(
TNode<Context> native_context);
TNode<NativeContext> native_context);
TNode<BoolT> IsPromiseSpeciesProtectorCellInvalid();
TNode<BoolT> IsMockArrayBufferAllocatorFlag() {

View File

@ -145,14 +145,6 @@ bool Isolate::IsTypedArraySpeciesLookupChainIntact() {
Smi::ToInt(species_cell.value()) == kProtectorValid;
}
bool Isolate::IsRegExpSpeciesLookupChainIntact(
Handle<NativeContext> native_context) {
DCHECK_EQ(*native_context, this->raw_native_context());
PropertyCell species_cell = native_context->regexp_species_protector();
return species_cell.value().IsSmi() &&
Smi::ToInt(species_cell.value()) == kProtectorValid;
}
bool Isolate::IsPromiseSpeciesLookupChainIntact() {
PropertyCell species_cell =
PropertyCell::cast(root(RootIndex::kPromiseSpeciesProtector));

View File

@ -4022,19 +4022,6 @@ void Isolate::InvalidateTypedArraySpeciesProtector() {
DCHECK(!IsTypedArraySpeciesLookupChainIntact());
}
void Isolate::InvalidateRegExpSpeciesProtector(
Handle<NativeContext> native_context) {
DCHECK_EQ(*native_context, this->raw_native_context());
DCHECK(native_context->regexp_species_protector().value().IsSmi());
DCHECK(IsRegExpSpeciesLookupChainIntact(native_context));
Handle<PropertyCell> species_cell(native_context->regexp_species_protector(),
this);
PropertyCell::SetValueWithInvalidation(
this, "regexp_species_protector", species_cell,
handle(Smi::FromInt(kProtectorInvalid), this));
DCHECK(!IsRegExpSpeciesLookupChainIntact(native_context));
}
void Isolate::InvalidatePromiseSpeciesProtector() {
DCHECK(factory()->promise_species_protector()->value().IsSmi());
DCHECK(IsPromiseSpeciesLookupChainIntact());

View File

@ -1177,8 +1177,6 @@ class Isolate final : private HiddenFactory {
inline bool IsArraySpeciesLookupChainIntact();
inline bool IsTypedArraySpeciesLookupChainIntact();
inline bool IsRegExpSpeciesLookupChainIntact(
Handle<NativeContext> native_context);
// Check that the @@species protector is intact, which guards the lookup of
// "constructor" on JSPromise instances, whose [[Prototype]] is the initial

View File

@ -0,0 +1,27 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_EXECUTION_PROTECTORS_INL_H_
#define V8_EXECUTION_PROTECTORS_INL_H_
#include "src/execution/protectors.h"
#include "src/objects/contexts-inl.h"
#include "src/objects/property-cell-inl.h"
#include "src/objects/smi.h"
namespace v8 {
namespace internal {
#define DEFINE_PROTECTOR_CHECK(name, cell) \
bool Protectors::Is##name##Intact(Handle<NativeContext> native_context) { \
PropertyCell species_cell = native_context->cell(); \
return species_cell.value().IsSmi() && \
Smi::ToInt(species_cell.value()) == kProtectorValid; \
}
DECLARED_PROTECTORS(DEFINE_PROTECTOR_CHECK)
} // namespace internal
} // namespace v8
#endif // V8_EXECUTION_PROTECTORS_INL_H_

View File

@ -0,0 +1,35 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/execution/protectors.h"
#include "src/execution/isolate-inl.h"
#include "src/execution/protectors-inl.h"
#include "src/handles/handles-inl.h"
#include "src/objects/contexts.h"
#include "src/objects/property-cell.h"
#include "src/objects/smi.h"
#include "src/tracing/trace-event.h"
#include "src/utils/utils.h"
namespace v8 {
namespace internal {
#define INVALIDATE_PROTECTOR_DEFINITION(name, cell) \
void Protectors::Invalidate##name(Isolate* isolate, \
Handle<NativeContext> native_context) { \
DCHECK_EQ(*native_context, isolate->raw_native_context()); \
DCHECK(native_context->cell().value().IsSmi()); \
DCHECK(Is##name##Intact(native_context)); \
Handle<PropertyCell> species_cell(native_context->cell(), isolate); \
PropertyCell::SetValueWithInvalidation( \
isolate, #cell, species_cell, \
handle(Smi::FromInt(kProtectorInvalid), isolate)); \
DCHECK(!Is##name##Intact(native_context)); \
}
DECLARED_PROTECTORS(INVALIDATE_PROTECTOR_DEFINITION)
#undef INVALIDATE_PROTECTOR_DEFINITION
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,32 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_EXECUTION_PROTECTORS_H_
#define V8_EXECUTION_PROTECTORS_H_
#include "src/handles/handles.h"
namespace v8 {
namespace internal {
class Protectors : public AllStatic {
public:
static const int kProtectorValid = 1;
static const int kProtectorInvalid = 0;
#define DECLARED_PROTECTORS(V) \
V(RegExpSpeciesLookupChainProtector, regexp_species_protector)
#define DECLARE_PROTECTOR(name, unused_cell) \
static inline bool Is##name##Intact(Handle<NativeContext> native_context); \
static void Invalidate##name(Isolate* isolate, \
Handle<NativeContext> native_context);
DECLARED_PROTECTORS(DECLARE_PROTECTOR)
#undef DECLARE_PROTECTOR
};
} // namespace internal
} // namespace v8
#endif // V8_EXECUTION_PROTECTORS_H_

View File

@ -234,7 +234,6 @@ enum ContextLookupFlags {
V(REGEXP_REPLACE_FUNCTION_INDEX, JSFunction, regexp_replace_function) \
V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map) \
V(REGEXP_SEARCH_FUNCTION_INDEX, JSFunction, regexp_search_function) \
V(REGEXP_SPECIES_PROTECTOR_INDEX, PropertyCell, regexp_species_protector) \
V(REGEXP_SPLIT_FUNCTION_INDEX, JSFunction, regexp_split_function) \
V(INITIAL_REGEXP_STRING_ITERATOR_PROTOTYPE_MAP_INDEX, Map, \
initial_regexp_string_iterator_prototype_map) \
@ -254,6 +253,8 @@ enum ContextLookupFlags {
slow_object_with_object_prototype_map) \
V(SLOW_TEMPLATE_INSTANTIATIONS_CACHE_INDEX, SimpleNumberDictionary, \
slow_template_instantiations_cache) \
/* Fast Path Protectors */ \
V(REGEXP_SPECIES_PROTECTOR_INDEX, PropertyCell, regexp_species_protector) \
/* All *_FUNCTION_MAP_INDEX definitions used by Context::FunctionMapIndex */ \
/* must remain together. */ \
V(SLOPPY_FUNCTION_MAP_INDEX, Map, sloppy_function_map) \

View File

@ -6,6 +6,7 @@
#include "src/deoptimizer/deoptimizer.h"
#include "src/execution/isolate-inl.h"
#include "src/execution/protectors-inl.h"
#include "src/init/bootstrapper.h"
#include "src/logging/counters.h"
#include "src/objects/elements.h"
@ -241,7 +242,8 @@ void LookupIterator::InternalUpdateProtector() {
if (*name_ == roots.constructor_string()) {
if (!isolate_->IsArraySpeciesLookupChainIntact() &&
!isolate_->IsPromiseSpeciesLookupChainIntact() &&
!isolate_->IsRegExpSpeciesLookupChainIntact(native_context) &&
!Protectors::IsRegExpSpeciesLookupChainProtectorIntact(
native_context) &&
!isolate_->IsTypedArraySpeciesLookupChainIntact()) {
return;
}
@ -257,8 +259,12 @@ void LookupIterator::InternalUpdateProtector() {
isolate_->InvalidatePromiseSpeciesProtector();
return;
} else if (receiver->IsJSRegExp(isolate_)) {
if (!isolate_->IsRegExpSpeciesLookupChainIntact(native_context)) return;
isolate_->InvalidateRegExpSpeciesProtector(native_context);
if (!Protectors::IsRegExpSpeciesLookupChainProtectorIntact(
native_context)) {
return;
}
Protectors::InvalidateRegExpSpeciesLookupChainProtector(isolate_,
native_context);
return;
} else if (receiver->IsJSTypedArray(isolate_)) {
if (!isolate_->IsTypedArraySpeciesLookupChainIntact()) return;
@ -284,8 +290,12 @@ void LookupIterator::InternalUpdateProtector() {
isolate_->InvalidatePromiseSpeciesProtector();
} else if (isolate_->IsInAnyContext(*receiver,
Context::REGEXP_PROTOTYPE_INDEX)) {
if (!isolate_->IsRegExpSpeciesLookupChainIntact(native_context)) return;
isolate_->InvalidateRegExpSpeciesProtector(native_context);
if (!Protectors::IsRegExpSpeciesLookupChainProtectorIntact(
native_context)) {
return;
}
Protectors::InvalidateRegExpSpeciesLookupChainProtector(isolate_,
native_context);
} else if (isolate_->IsInAnyContext(
receiver->map(isolate_).prototype(isolate_),
Context::TYPED_ARRAY_PROTOTYPE_INDEX)) {
@ -323,7 +333,8 @@ void LookupIterator::InternalUpdateProtector() {
} else if (*name_ == roots.species_symbol()) {
if (!isolate_->IsArraySpeciesLookupChainIntact() &&
!isolate_->IsPromiseSpeciesLookupChainIntact() &&
!isolate_->IsRegExpSpeciesLookupChainIntact(native_context) &&
!Protectors::IsRegExpSpeciesLookupChainProtectorIntact(
native_context) &&
!isolate_->IsTypedArraySpeciesLookupChainIntact()) {
return;
}
@ -340,8 +351,12 @@ void LookupIterator::InternalUpdateProtector() {
isolate_->InvalidatePromiseSpeciesProtector();
} else if (isolate_->IsInAnyContext(*receiver,
Context::REGEXP_FUNCTION_INDEX)) {
if (!isolate_->IsRegExpSpeciesLookupChainIntact(native_context)) return;
isolate_->InvalidateRegExpSpeciesProtector(native_context);
if (!Protectors::IsRegExpSpeciesLookupChainProtectorIntact(
native_context)) {
return;
}
Protectors::InvalidateRegExpSpeciesLookupChainProtector(isolate_,
native_context);
} else if (IsTypedArrayFunctionInAnyContext(isolate_, *receiver)) {
if (!isolate_->IsTypedArraySpeciesLookupChainIntact()) return;
isolate_->InvalidateTypedArraySpeciesProtector();

View File

@ -5,6 +5,7 @@
#include "src/regexp/regexp-utils.h"
#include "src/execution/isolate.h"
#include "src/execution/protectors-inl.h"
#include "src/heap/factory.h"
#include "src/objects/js-regexp-inl.h"
#include "src/objects/objects-inl.h"
@ -185,7 +186,8 @@ bool RegExpUtils::IsUnmodifiedRegExp(Isolate* isolate, Handle<Object> obj) {
// property. Similar spots in CSA would use BranchIfFastRegExp_Strict in this
// case.
if (!isolate->IsRegExpSpeciesLookupChainIntact(isolate->native_context())) {
if (!Protectors::IsRegExpSpeciesLookupChainProtectorIntact(
isolate->native_context())) {
return false;
}