[api] Avoid handles for const API functions

Handles are notorious for preventing compiler optimizations. We should
avoid them for simple const functions.

- Mark more API functions const
- Mark more String functions const

Bug: v8:11195, chromium:808503, v8:11263
Change-Id: I9940e85600bc7d19027039d807b3313e2dcccdc7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2575065
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73159}
This commit is contained in:
Camillo Bruni 2021-03-03 10:22:44 +01:00 committed by Commit Bot
parent e3d4d9b44b
commit aee471b2ff
5 changed files with 218 additions and 224 deletions

View File

@ -1491,7 +1491,7 @@ class V8_EXPORT UnboundScript {
*/
Local<Script> BindToCurrentContext();
int GetId();
int GetId() const;
Local<Value> GetScriptName();
/**
@ -1701,7 +1701,7 @@ class V8_EXPORT Module : public Data {
*
* The module must be a SourceTextModule and must not have a kErrored status.
*/
int ScriptId();
int ScriptId() const;
/**
* Returns whether this module or any of its requested modules is async,
@ -3525,12 +3525,12 @@ class V8_EXPORT String : public Name {
/**
* Returns true if this string can be made external.
*/
bool CanMakeExternal();
bool CanMakeExternal() const;
/**
* Returns true if the strings values are equal. Same as JS ==/===.
*/
bool StringEquals(Local<String> str);
bool StringEquals(Local<String> str) const;
/**
* Converts an object to a UTF-8-encoded character array. Useful if
@ -4137,7 +4137,7 @@ class V8_EXPORT Object : public Value {
Maybe<bool> SetIntegrityLevel(Local<Context> context, IntegrityLevel level);
/** Gets the number of internal fields for this Object. */
int InternalFieldCount();
int InternalFieldCount() const;
/** Same as above, but works for PersistentBase. */
V8_INLINE static int InternalFieldCount(
@ -4247,10 +4247,10 @@ class V8_EXPORT Object : public Value {
Local<Context> context, Local<Name> key);
/** Tests for a named lookup interceptor.*/
bool HasNamedLookupInterceptor();
bool HasNamedLookupInterceptor() const;
/** Tests for an index lookup interceptor.*/
bool HasIndexedLookupInterceptor();
bool HasIndexedLookupInterceptor() const;
/**
* Returns the identity hash for this object. The current implementation
@ -4290,12 +4290,12 @@ class V8_EXPORT Object : public Value {
* ObjectTemplate::SetCallAsFunctionHandler method.
* When an Object is callable this method returns true.
*/
bool IsCallable();
bool IsCallable() const;
/**
* True if this object is a constructor.
*/
bool IsConstructor();
bool IsConstructor() const;
/**
* True if this object can carry information relevant to the embedder in its
@ -4304,14 +4304,14 @@ class V8_EXPORT Object : public Value {
* V8 automatically adds internal fields at compile time, such as e.g.
* v8::ArrayBuffer.
*/
bool IsApiWrapper();
bool IsApiWrapper() const;
/**
* True if this object was created from an object template which was marked
* as undetectable. See v8::ObjectTemplate::MarkAsUndetectable for more
* information.
*/
bool IsUndetectable();
bool IsUndetectable() const;
/**
* Call an Object as a function if a callback is set by the
@ -4370,7 +4370,7 @@ class V8_EXPORT Object : public Value {
*
* See also: v8::ObjectTemplate::SetCodeLike
*/
bool IsCodeLike(Isolate* isolate);
bool IsCodeLike(Isolate* isolate) const;
private:
Object();
@ -4868,7 +4868,7 @@ class V8_EXPORT Promise : public Object {
* Returns true if the promise has at least one derived promise, and
* therefore resolve/reject handlers (including default handler).
*/
bool HasHandler();
bool HasHandler() const;
/**
* Returns the content of the [[PromiseResult]] field. The Promise must not
@ -4976,7 +4976,7 @@ class V8_EXPORT Proxy : public Object {
public:
Local<Value> GetTarget();
Local<Value> GetHandler();
bool IsRevoked();
bool IsRevoked() const;
void Revoke();
/**
@ -7168,7 +7168,7 @@ class V8_EXPORT ObjectTemplate : public Template {
* Gets the number of internal fields for objects generated from
* this template.
*/
int InternalFieldCount();
int InternalFieldCount() const;
/**
* Sets the number of internal fields for objects generated from
@ -7179,7 +7179,7 @@ class V8_EXPORT ObjectTemplate : public Template {
/**
* Returns true if the object will be an immutable prototype exotic object.
*/
bool IsImmutableProto();
bool IsImmutableProto() const;
/**
* Makes the ObjectTemplate for an immutable prototype exotic object, with an
@ -7197,7 +7197,7 @@ class V8_EXPORT ObjectTemplate : public Template {
* Reference: https://github.com/tc39/proposal-dynamic-code-brand-checks
*/
void SetCodeLike();
bool IsCodeLike();
bool IsCodeLike() const;
V8_INLINE static ObjectTemplate* Cast(Data* data);
@ -10735,7 +10735,7 @@ class V8_EXPORT Context : public Data {
* Returns true if code generation from strings is allowed for the context.
* For more details see AllowCodeGenerationFromStrings(bool) documentation.
*/
bool IsCodeGenerationFromStringsAllowed();
bool IsCodeGenerationFromStringsAllowed() const;
/**
* Sets the error description for the exception that is thrown when

View File

@ -932,11 +932,9 @@ bool Data::IsModule() const { return Utils::OpenHandle(this)->IsModule(); }
bool Data::IsValue() const {
i::DisallowGarbageCollection no_gc;
i::Handle<i::Object> self = Utils::OpenHandle(this);
if (self->IsSmi()) {
return true;
}
i::HeapObject heap_object = i::HeapObject::cast(*self);
i::Object self = *Utils::OpenHandle(this);
if (self.IsSmi()) return true;
i::HeapObject heap_object = i::HeapObject::cast(self);
DCHECK(!heap_object.IsTheHole());
if (heap_object.IsSymbol()) {
return !i::Symbol::cast(heap_object).is_private();
@ -1760,7 +1758,7 @@ void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
i::FunctionTemplateInfo::SetInstanceCallHandler(isolate, cons, obj);
}
int ObjectTemplate::InternalFieldCount() {
int ObjectTemplate::InternalFieldCount() const {
return Utils::OpenHandle(this)->embedder_field_count();
}
@ -1781,7 +1779,7 @@ void ObjectTemplate::SetInternalFieldCount(int value) {
Utils::OpenHandle(this)->set_embedder_field_count(value);
}
bool ObjectTemplate::IsImmutableProto() {
bool ObjectTemplate::IsImmutableProto() const {
return Utils::OpenHandle(this)->immutable_proto();
}
@ -1792,7 +1790,7 @@ void ObjectTemplate::SetImmutableProto() {
self->set_immutable_proto(true);
}
bool ObjectTemplate::IsCodeLike() {
bool ObjectTemplate::IsCodeLike() const {
return Utils::OpenHandle(this)->code_like();
}
@ -1843,15 +1841,11 @@ Local<Script> UnboundScript::BindToCurrentContext() {
return ToApiHandle<Script>(function);
}
int UnboundScript::GetId() {
auto function_info =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
i::Isolate* isolate = function_info->GetIsolate();
int UnboundScript::GetId() const {
auto function_info = i::SharedFunctionInfo::cast(*Utils::OpenHandle(this));
i::Isolate* isolate = function_info.GetIsolate();
LOG_API(isolate, UnboundScript, GetId);
i::HandleScope scope(isolate);
i::Handle<i::Script> script(i::Script::cast(function_info->script()),
isolate);
return script->id();
return i::Script::cast(function_info.script()).id();
}
int UnboundScript::GetLineNumber(int code_pos) {
@ -2051,13 +2045,10 @@ Local<Value> Module::GetException() const {
}
int Module::GetModuleRequestsLength() const {
i::Handle<i::Module> self = Utils::OpenHandle(this);
if (self->IsSyntheticModule()) return 0;
ASSERT_NO_SCRIPT_NO_EXCEPTION(self->GetIsolate());
return i::Handle<i::SourceTextModule>::cast(self)
->info()
.module_requests()
.length();
i::Module self = *Utils::OpenHandle(this);
if (self.IsSyntheticModule()) return 0;
ASSERT_NO_SCRIPT_NO_EXCEPTION(self.GetIsolate());
return i::SourceTextModule::cast(self).info().module_requests().length();
}
Local<String> Module::GetModuleRequest(int i) const {
@ -2158,22 +2149,22 @@ Local<UnboundModuleScript> Module::GetUnboundModuleScript() {
isolate));
}
int Module::ScriptId() {
i::Handle<i::Module> self = Utils::OpenHandle(this);
Utils::ApiCheck(self->IsSourceTextModule(), "v8::Module::ScriptId",
int Module::ScriptId() const {
i::Module self = *Utils::OpenHandle(this);
Utils::ApiCheck(self.IsSourceTextModule(), "v8::Module::ScriptId",
"v8::Module::ScriptId must be used on an SourceTextModule");
ASSERT_NO_SCRIPT_NO_EXCEPTION(self->GetIsolate());
return i::Handle<i::SourceTextModule>::cast(self)->GetScript().id();
ASSERT_NO_SCRIPT_NO_EXCEPTION(self.GetIsolate());
return i::SourceTextModule::cast(self).GetScript().id();
}
bool Module::IsGraphAsync() const {
Utils::ApiCheck(
GetStatus() >= kInstantiated, "v8::Module::IsGraphAsync",
"v8::Module::IsGraphAsync must be used on an instantiated module");
i::Handle<i::Module> self = Utils::OpenHandle(this);
auto isolate = self->GetIsolate();
i::Module self = *Utils::OpenHandle(this);
auto isolate = self.GetIsolate();
ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
return self->IsGraphAsync(isolate);
return self.IsGraphAsync(isolate);
}
bool Module::IsSourceTextModule() const {
@ -3282,15 +3273,15 @@ bool Value::FullIsNull() const {
}
bool Value::IsTrue() const {
i::Handle<i::Object> object = Utils::OpenHandle(this);
if (object->IsSmi()) return false;
return object->IsTrue();
i::Object object = *Utils::OpenHandle(this);
if (object.IsSmi()) return false;
return object.IsTrue();
}
bool Value::IsFalse() const {
i::Handle<i::Object> object = Utils::OpenHandle(this);
if (object->IsSmi()) return false;
return object->IsFalse();
i::Object object = *Utils::OpenHandle(this);
if (object.IsSmi()) return false;
return object.IsFalse();
}
bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); }
@ -3310,8 +3301,9 @@ bool Value::IsSymbol() const {
bool Value::IsArray() const { return Utils::OpenHandle(this)->IsJSArray(); }
bool Value::IsArrayBuffer() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
return obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj).is_shared();
i::Object obj = *Utils::OpenHandle(this);
if (!obj.IsJSArrayBuffer()) return false;
return !i::JSArrayBuffer::cast(obj).is_shared();
}
bool Value::IsArrayBufferView() const {
@ -3338,8 +3330,9 @@ bool Value::IsDataView() const {
}
bool Value::IsSharedArrayBuffer() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
return obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj).is_shared();
i::Object obj = *Utils::OpenHandle(this);
if (!obj.IsJSArrayBuffer()) return false;
return i::JSArrayBuffer::cast(obj).is_shared();
}
bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); }
@ -3380,23 +3373,23 @@ VALUE_IS_SPECIFIC_TYPE(WeakSet, JSWeakSet)
bool Value::IsBoolean() const { return Utils::OpenHandle(this)->IsBoolean(); }
bool Value::IsExternal() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (!obj->IsHeapObject()) return false;
i::Handle<i::HeapObject> heap_obj = i::Handle<i::HeapObject>::cast(obj);
i::Object obj = *Utils::OpenHandle(this);
if (!obj.IsHeapObject()) return false;
i::HeapObject heap_obj = i::HeapObject::cast(obj);
// Check the instance type is JS_OBJECT (instance type of Externals) before
// attempting to get the Isolate since that guarantees the object is writable
// and GetIsolate will work.
if (heap_obj->map().instance_type() != i::JS_OBJECT_TYPE) return false;
i::Isolate* isolate = i::JSObject::cast(*heap_obj).GetIsolate();
if (heap_obj.map().instance_type() != i::JS_OBJECT_TYPE) return false;
i::Isolate* isolate = i::JSObject::cast(heap_obj).GetIsolate();
ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
return heap_obj->IsExternal(isolate);
return heap_obj.IsExternal(isolate);
}
bool Value::IsInt32() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (obj->IsSmi()) return true;
if (obj->IsNumber()) {
return i::IsInt32Double(obj->Number());
i::Object obj = *Utils::OpenHandle(this);
if (obj.IsSmi()) return true;
if (obj.IsNumber()) {
return i::IsInt32Double(obj.Number());
}
return false;
}
@ -3422,18 +3415,18 @@ bool Value::IsRegExp() const {
}
bool Value::IsAsyncFunction() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (!obj->IsJSFunction()) return false;
i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj);
return i::IsAsyncFunction(func->shared().kind());
i::Object obj = *Utils::OpenHandle(this);
if (!obj.IsJSFunction()) return false;
i::JSFunction func = i::JSFunction::cast(obj);
return i::IsAsyncFunction(func.shared().kind());
}
bool Value::IsGeneratorFunction() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (!obj->IsJSFunction()) return false;
i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj);
ASSERT_NO_SCRIPT_NO_EXCEPTION(func->GetIsolate());
return i::IsGeneratorFunction(func->shared().kind());
i::Object obj = *Utils::OpenHandle(this);
if (!obj.IsJSFunction()) return false;
i::JSFunction func = i::JSFunction::cast(obj);
ASSERT_NO_SCRIPT_NO_EXCEPTION(func.GetIsolate());
return i::IsGeneratorFunction(func.shared().kind());
}
bool Value::IsGeneratorObject() const {
@ -4637,16 +4630,16 @@ Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context,
return result;
}
bool v8::Object::HasNamedLookupInterceptor() {
auto self = Utils::OpenHandle(this);
return self->IsJSObject() &&
i::Handle<i::JSObject>::cast(self)->HasNamedInterceptor();
bool v8::Object::HasNamedLookupInterceptor() const {
auto self = *Utils::OpenHandle(this);
if (self.IsJSObject()) return false;
return i::JSObject::cast(self).HasNamedInterceptor();
}
bool v8::Object::HasIndexedLookupInterceptor() {
auto self = Utils::OpenHandle(this);
return self->IsJSObject() &&
i::Handle<i::JSObject>::cast(self)->HasIndexedInterceptor();
bool v8::Object::HasIndexedLookupInterceptor() const {
auto self = *Utils::OpenHandle(this);
if (self.IsJSObject()) return false;
return i::JSObject::cast(self).HasIndexedInterceptor();
}
MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
@ -4781,22 +4774,22 @@ int v8::Object::GetIdentityHash() {
return self->GetOrCreateIdentityHash(isolate).value();
}
bool v8::Object::IsCallable() {
bool v8::Object::IsCallable() const {
auto self = Utils::OpenHandle(this);
return self->IsCallable();
}
bool v8::Object::IsConstructor() {
bool v8::Object::IsConstructor() const {
auto self = Utils::OpenHandle(this);
return self->IsConstructor();
}
bool v8::Object::IsApiWrapper() {
bool v8::Object::IsApiWrapper() const {
auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
return self->IsApiWrapper();
}
bool v8::Object::IsUndetectable() {
bool v8::Object::IsUndetectable() const {
auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
return self->IsUndetectable();
}
@ -5037,17 +5030,11 @@ int Function::GetScriptColumnNumber() const {
}
int Function::ScriptId() const {
auto self = Utils::OpenHandle(this);
if (!self->IsJSFunction()) {
return v8::UnboundScript::kNoScriptId;
}
auto func = i::Handle<i::JSFunction>::cast(self);
if (!func->shared().script().IsScript()) {
return v8::UnboundScript::kNoScriptId;
}
i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
func->GetIsolate());
return script->id();
i::JSReceiver self = *Utils::OpenHandle(this);
if (!self.IsJSFunction()) return v8::UnboundScript::kNoScriptId;
auto func = i::JSFunction::cast(self);
if (!func.shared().script().IsScript()) return v8::UnboundScript::kNoScriptId;
return i::Script::cast(func.shared().script()).id();
}
Local<v8::Value> Function::GetBoundFunction() const {
@ -5581,36 +5568,36 @@ bool Boolean::Value() const {
}
int64_t Integer::Value() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (obj->IsSmi()) {
return i::Smi::ToInt(*obj);
i::Object obj = *Utils::OpenHandle(this);
if (obj.IsSmi()) {
return i::Smi::ToInt(obj);
} else {
return static_cast<int64_t>(obj->Number());
return static_cast<int64_t>(obj.Number());
}
}
int32_t Int32::Value() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (obj->IsSmi()) {
return i::Smi::ToInt(*obj);
i::Object obj = *Utils::OpenHandle(this);
if (obj.IsSmi()) {
return i::Smi::ToInt(obj);
} else {
return static_cast<int32_t>(obj->Number());
return static_cast<int32_t>(obj.Number());
}
}
uint32_t Uint32::Value() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
if (obj->IsSmi()) {
return i::Smi::ToInt(*obj);
i::Object obj = *Utils::OpenHandle(this);
if (obj.IsSmi()) {
return i::Smi::ToInt(obj);
} else {
return static_cast<uint32_t>(obj->Number());
return static_cast<uint32_t>(obj.Number());
}
}
int v8::Object::InternalFieldCount() {
i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
if (!self->IsJSObject()) return 0;
return i::Handle<i::JSObject>::cast(self)->GetEmbedderFieldCount();
int v8::Object::InternalFieldCount() const {
i::JSReceiver self = *Utils::OpenHandle(this);
if (!self.IsJSObject()) return 0;
return i::JSObject::cast(self).GetEmbedderFieldCount();
}
static bool InternalFieldOK(i::Handle<i::JSReceiver> obj, int index,
@ -6141,9 +6128,9 @@ void Context::AllowCodeGenerationFromStrings(bool allow) {
: i::ReadOnlyRoots(isolate).false_value());
}
bool Context::IsCodeGenerationFromStringsAllowed() {
i::Handle<i::Context> context = Utils::OpenHandle(this);
return !context->allow_code_gen_from_strings().IsFalse(context->GetIsolate());
bool Context::IsCodeGenerationFromStringsAllowed() const {
i::Context context = *Utils::OpenHandle(this);
return !context.allow_code_gen_from_strings().IsFalse(context.GetIsolate());
}
void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
@ -6548,8 +6535,7 @@ bool v8::String::MakeExternal(
return result;
}
bool v8::String::CanMakeExternal() {
i::DisallowGarbageCollection no_gc;
bool v8::String::CanMakeExternal() const {
i::String obj = *Utils::OpenHandle(this);
if (obj.IsThinString()) {
@ -6564,7 +6550,7 @@ bool v8::String::CanMakeExternal() {
return !i::Heap::InYoungGeneration(obj);
}
bool v8::String::StringEquals(Local<String> that) {
bool v8::String::StringEquals(Local<String> that) const {
auto self = Utils::OpenHandle(this);
auto other = Utils::OpenHandle(*that);
return self->Equals(*other);
@ -6736,12 +6722,11 @@ Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) {
}
bool v8::BooleanObject::ValueOf() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
i::Handle<i::JSPrimitiveWrapper>::cast(obj);
i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
i::Object obj = *Utils::OpenHandle(this);
i::JSPrimitiveWrapper js_primitive_wrapper = i::JSPrimitiveWrapper::cast(obj);
i::Isolate* isolate = js_primitive_wrapper.GetIsolate();
LOG_API(isolate, BooleanObject, BooleanValue);
return js_primitive_wrapper->value().IsTrue(isolate);
return js_primitive_wrapper.value().IsTrue(isolate);
}
Local<v8::Value> v8::StringObject::New(Isolate* v8_isolate,
@ -7268,16 +7253,13 @@ MaybeLocal<Promise> Promise::Then(Local<Context> context,
RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
}
bool Promise::HasHandler() {
i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
i::Isolate* isolate = promise->GetIsolate();
bool Promise::HasHandler() const {
i::JSReceiver promise = *Utils::OpenHandle(this);
i::Isolate* isolate = promise.GetIsolate();
LOG_API(isolate, Promise, HasRejectHandler);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
if (promise->IsJSPromise()) {
i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
return js_promise->has_handler();
}
return false;
if (!promise.IsJSPromise()) return false;
return i::JSPromise::cast(promise).has_handler();
}
Local<Value> Promise::Result() {
@ -7316,7 +7298,7 @@ Local<Value> Proxy::GetHandler() {
return Utils::ToLocal(handler);
}
bool Proxy::IsRevoked() {
bool Proxy::IsRevoked() const {
i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
return self->IsRevoked();
}
@ -9284,7 +9266,7 @@ void v8::Isolate::LocaleConfigurationChangeNotification() {
#endif // V8_INTL_SUPPORT
}
bool v8::Object::IsCodeLike(v8::Isolate* isolate) {
bool v8::Object::IsCodeLike(v8::Isolate* isolate) const {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
LOG_API(i_isolate, Object, IsCodeLike);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
@ -9335,18 +9317,21 @@ MicrotasksScope::~MicrotasksScope() {
#endif
}
// static
void MicrotasksScope::PerformCheckpoint(Isolate* v8_isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
auto* microtask_queue = isolate->default_microtask_queue();
microtask_queue->PerformCheckpoint(v8_isolate);
}
// static
int MicrotasksScope::GetCurrentDepth(Isolate* v8_isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
auto* microtask_queue = isolate->default_microtask_queue();
return microtask_queue->GetMicrotasksScopeDepth();
}
// static
bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8_isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
auto* microtask_queue = isolate->default_microtask_queue();

View File

@ -133,49 +133,51 @@ StringShape::StringShape(InstanceType t) : type_(static_cast<uint32_t>(t)) {
DCHECK_EQ(type_ & kIsNotStringMask, kStringTag);
}
bool StringShape::IsInternalized() {
bool StringShape::IsInternalized() const {
DCHECK(valid());
STATIC_ASSERT(kNotInternalizedTag != 0);
return (type_ & (kIsNotStringMask | kIsNotInternalizedMask)) ==
(kStringTag | kInternalizedTag);
}
bool StringShape::IsCons() {
bool StringShape::IsCons() const {
return (type_ & kStringRepresentationMask) == kConsStringTag;
}
bool StringShape::IsThin() {
bool StringShape::IsThin() const {
return (type_ & kStringRepresentationMask) == kThinStringTag;
}
bool StringShape::IsSliced() {
bool StringShape::IsSliced() const {
return (type_ & kStringRepresentationMask) == kSlicedStringTag;
}
bool StringShape::IsIndirect() {
bool StringShape::IsIndirect() const {
return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
}
bool StringShape::IsExternal() {
bool StringShape::IsExternal() const {
return (type_ & kStringRepresentationMask) == kExternalStringTag;
}
bool StringShape::IsSequential() {
bool StringShape::IsSequential() const {
return (type_ & kStringRepresentationMask) == kSeqStringTag;
}
bool StringShape::IsUncachedExternal() {
bool StringShape::IsUncachedExternal() const {
return (type_ & kUncachedExternalStringMask) == kUncachedExternalStringTag;
}
StringRepresentationTag StringShape::representation_tag() {
StringRepresentationTag StringShape::representation_tag() const {
uint32_t tag = (type_ & kStringRepresentationMask);
return static_cast<StringRepresentationTag>(tag);
}
uint32_t StringShape::encoding_tag() { return type_ & kStringEncodingMask; }
uint32_t StringShape::encoding_tag() const {
return type_ & kStringEncodingMask;
}
uint32_t StringShape::full_representation_tag() {
uint32_t StringShape::full_representation_tag() const {
return (type_ & (kStringRepresentationMask | kStringEncodingMask));
}
@ -185,15 +187,15 @@ STATIC_ASSERT((kStringRepresentationMask | kStringEncodingMask) ==
STATIC_ASSERT(static_cast<uint32_t>(kStringEncodingMask) ==
Internals::kStringEncodingMask);
bool StringShape::IsSequentialOneByte() {
bool StringShape::IsSequentialOneByte() const {
return full_representation_tag() == (kSeqStringTag | kOneByteStringTag);
}
bool StringShape::IsSequentialTwoByte() {
bool StringShape::IsSequentialTwoByte() const {
return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
}
bool StringShape::IsExternalOneByte() {
bool StringShape::IsExternalOneByte() const {
return full_representation_tag() == (kExternalStringTag | kOneByteStringTag);
}
@ -202,7 +204,7 @@ STATIC_ASSERT((kExternalStringTag | kOneByteStringTag) ==
STATIC_ASSERT(v8::String::ONE_BYTE_ENCODING == kOneByteStringTag);
bool StringShape::IsExternalTwoByte() {
bool StringShape::IsExternalTwoByte() const {
return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
}
@ -298,7 +300,7 @@ bool String::IsOneByteRepresentationUnderneath(String string) {
}
}
uc32 FlatStringReader::Get(int index) {
uc32 FlatStringReader::Get(int index) const {
if (is_one_byte_) {
return Get<uint8_t>(index);
} else {
@ -307,7 +309,7 @@ uc32 FlatStringReader::Get(int index) {
}
template <typename Char>
Char FlatStringReader::Get(int index) {
Char FlatStringReader::Get(int index) const {
DCHECK_EQ(is_one_byte_, sizeof(Char) == 1);
DCHECK(0 <= index && index < length_);
if (sizeof(Char) == 1) {
@ -432,7 +434,7 @@ class SeqSubStringKey final : public StringTableKey {
using SeqOneByteSubStringKey = SeqSubStringKey<SeqOneByteString>;
using SeqTwoByteSubStringKey = SeqSubStringKey<SeqTwoByteString>;
bool String::Equals(String other) {
bool String::Equals(String other) const {
if (other == *this) return true;
if (this->IsInternalizedString() && other.IsInternalizedString()) {
return false;
@ -440,6 +442,7 @@ bool String::Equals(String other) {
return SlowEquals(other);
}
// static
bool String::Equals(Isolate* isolate, Handle<String> one, Handle<String> two) {
if (one.is_identical_to(two)) return true;
if (one->IsInternalizedString() && two->IsInternalizedString()) {
@ -539,7 +542,7 @@ bool String::IsEqualToImpl(
bool String::IsOneByteEqualTo(Vector<const char> str) { return IsEqualTo(str); }
template <typename Char>
const Char* String::GetChars(const DisallowGarbageCollection& no_gc) {
const Char* String::GetChars(const DisallowGarbageCollection& no_gc) const {
DCHECK(!SharedStringAccessGuardIfNeeded::IsNeeded(*this));
return StringShape(*this).IsExternal()
? CharTraits<Char>::ExternalString::cast(*this).GetChars()
@ -549,7 +552,7 @@ const Char* String::GetChars(const DisallowGarbageCollection& no_gc) {
template <typename Char>
const Char* String::GetChars(
const DisallowGarbageCollection& no_gc,
const SharedStringAccessGuardIfNeeded& access_guard) {
const SharedStringAccessGuardIfNeeded& access_guard) const {
return StringShape(*this).IsExternal()
? CharTraits<Char>::ExternalString::cast(*this).GetChars()
: CharTraits<Char>::String::cast(*this).GetChars(no_gc,
@ -580,17 +583,17 @@ Handle<String> String::Flatten(LocalIsolate* isolate, Handle<String> string,
return string;
}
uint16_t String::Get(int index, Isolate* isolate) {
uint16_t String::Get(int index, Isolate* isolate) const {
DCHECK(!SharedStringAccessGuardIfNeeded::IsNeeded(*this));
return GetImpl(index);
}
uint16_t String::Get(int index, LocalIsolate* local_isolate) {
uint16_t String::Get(int index, LocalIsolate* local_isolate) const {
SharedStringAccessGuardIfNeeded scope(local_isolate);
return GetImpl(index);
}
uint16_t String::GetImpl(int index) {
uint16_t String::GetImpl(int index) const {
DCHECK(index >= 0 && index < length());
class StringGetDispatcher : public AllStatic {
@ -619,12 +622,12 @@ void String::Set(int index, uint16_t value) {
: SeqTwoByteString::cast(*this).SeqTwoByteStringSet(index, value);
}
bool String::IsFlat() {
bool String::IsFlat() const {
if (!StringShape(*this).IsCons()) return true;
return ConsString::cast(*this).second().length() == 0;
}
String String::GetUnderlying() {
String String::GetUnderlying() const {
// Giving direct access to underlying string only makes sense if the
// wrapping string is already flattened.
DCHECK(this->IsFlat());
@ -728,7 +731,7 @@ uint32_t String::ToValidIndex(Object number) {
return index;
}
uint8_t SeqOneByteString::Get(int index) {
uint8_t SeqOneByteString::Get(int index) const {
DCHECK(index >= 0 && index < length());
return ReadField<byte>(kHeaderSize + index * kCharSize);
}
@ -738,11 +741,12 @@ void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) {
WriteField<byte>(kHeaderSize + index * kCharSize, static_cast<byte>(value));
}
Address SeqOneByteString::GetCharsAddress() {
Address SeqOneByteString::GetCharsAddress() const {
return field_address(kHeaderSize);
}
uint8_t* SeqOneByteString::GetChars(const DisallowGarbageCollection& no_gc) {
uint8_t* SeqOneByteString::GetChars(
const DisallowGarbageCollection& no_gc) const {
USE(no_gc);
DCHECK(!SharedStringAccessGuardIfNeeded::IsNeeded(*this));
return reinterpret_cast<uint8_t*>(GetCharsAddress());
@ -750,17 +754,17 @@ uint8_t* SeqOneByteString::GetChars(const DisallowGarbageCollection& no_gc) {
uint8_t* SeqOneByteString::GetChars(
const DisallowGarbageCollection& no_gc,
const SharedStringAccessGuardIfNeeded& access_guard) {
const SharedStringAccessGuardIfNeeded& access_guard) const {
USE(no_gc);
USE(access_guard);
return reinterpret_cast<uint8_t*>(GetCharsAddress());
}
Address SeqTwoByteString::GetCharsAddress() {
Address SeqTwoByteString::GetCharsAddress() const {
return field_address(kHeaderSize);
}
uc16* SeqTwoByteString::GetChars(const DisallowGarbageCollection& no_gc) {
uc16* SeqTwoByteString::GetChars(const DisallowGarbageCollection& no_gc) const {
USE(no_gc);
DCHECK(!SharedStringAccessGuardIfNeeded::IsNeeded(*this));
return reinterpret_cast<uc16*>(GetCharsAddress());
@ -768,13 +772,13 @@ uc16* SeqTwoByteString::GetChars(const DisallowGarbageCollection& no_gc) {
uc16* SeqTwoByteString::GetChars(
const DisallowGarbageCollection& no_gc,
const SharedStringAccessGuardIfNeeded& access_guard) {
const SharedStringAccessGuardIfNeeded& access_guard) const {
USE(no_gc);
USE(access_guard);
return reinterpret_cast<uc16*>(GetCharsAddress());
}
uint16_t SeqTwoByteString::Get(int index) {
uint16_t SeqTwoByteString::Get(int index) const {
DCHECK(index >= 0 && index < length());
return ReadField<uint16_t>(kHeaderSize + index * kShortSize);
}
@ -901,7 +905,7 @@ void ExternalOneByteString::set_resource(
if (resource != nullptr) update_data_cache(isolate);
}
const uint8_t* ExternalOneByteString::GetChars() {
const uint8_t* ExternalOneByteString::GetChars() const {
DisallowGarbageCollection no_gc;
if (is_uncached()) {
if (resource()->IsCacheable()) {
@ -923,7 +927,7 @@ const uint8_t* ExternalOneByteString::GetChars() {
return reinterpret_cast<const uint8_t*>(resource()->data());
}
uint8_t ExternalOneByteString::Get(int index) {
uint8_t ExternalOneByteString::Get(int index) const {
DCHECK(index >= 0 && index < length());
return GetChars()[index];
}
@ -966,7 +970,7 @@ void ExternalTwoByteString::set_resource(
if (resource != nullptr) update_data_cache(isolate);
}
const uint16_t* ExternalTwoByteString::GetChars() {
const uint16_t* ExternalTwoByteString::GetChars() const {
DisallowGarbageCollection no_gc;
if (is_uncached()) {
if (resource()->IsCacheable()) {
@ -988,7 +992,7 @@ const uint16_t* ExternalTwoByteString::GetChars() {
return resource()->data();
}
uint16_t ExternalTwoByteString::Get(int index) {
uint16_t ExternalTwoByteString::Get(int index) const {
DCHECK(index >= 0 && index < length());
return GetChars()[index];
}

View File

@ -773,7 +773,7 @@ template Handle<FixedArray> String::CalculateLineEnds(LocalIsolate* isolate,
Handle<String> src,
bool include_ending_line);
bool String::SlowEquals(String other) {
bool String::SlowEquals(String other) const {
DisallowGarbageCollection no_gc;
// Fast check: negative check with lengths.
int len = length();
@ -825,6 +825,7 @@ bool String::SlowEquals(String other) {
return comparator.Equals(*this, other);
}
// static
bool String::SlowEquals(Isolate* isolate, Handle<String> one,
Handle<String> two) {
// Fast check: negative check with lengths.
@ -1437,7 +1438,7 @@ void SeqTwoByteString::clear_padding() {
SizeFor(length()) - data_size);
}
uint16_t ConsString::Get(int index) {
uint16_t ConsString::Get(int index) const {
DCHECK(index >= 0 && index < this->length());
// Check for a flattened cons string
@ -1466,9 +1467,11 @@ uint16_t ConsString::Get(int index) {
UNREACHABLE();
}
uint16_t ThinString::Get(int index) { return actual().Get(index); }
uint16_t ThinString::Get(int index) const { return actual().Get(index); }
uint16_t SlicedString::Get(int index) { return parent().Get(offset() + index); }
uint16_t SlicedString::Get(int index) const {
return parent().Get(offset() + index);
}
int ExternalString::ExternalPayloadSize() const {
int length_multiplier = IsTwoByteRepresentation() ? i::kShortSize : kCharSize;

View File

@ -44,25 +44,25 @@ class StringShape {
inline explicit StringShape(const String s);
inline explicit StringShape(Map s);
inline explicit StringShape(InstanceType t);
inline bool IsSequential();
inline bool IsExternal();
inline bool IsCons();
inline bool IsSliced();
inline bool IsThin();
inline bool IsIndirect();
inline bool IsUncachedExternal();
inline bool IsExternalOneByte();
inline bool IsExternalTwoByte();
inline bool IsSequentialOneByte();
inline bool IsSequentialTwoByte();
inline bool IsInternalized();
inline StringRepresentationTag representation_tag();
inline uint32_t encoding_tag();
inline uint32_t full_representation_tag();
inline bool IsSequential() const;
inline bool IsExternal() const;
inline bool IsCons() const;
inline bool IsSliced() const;
inline bool IsThin() const;
inline bool IsIndirect() const;
inline bool IsUncachedExternal() const;
inline bool IsExternalOneByte() const;
inline bool IsExternalTwoByte() const;
inline bool IsSequentialOneByte() const;
inline bool IsSequentialTwoByte() const;
inline bool IsInternalized() const;
inline StringRepresentationTag representation_tag() const;
inline uint32_t encoding_tag() const;
inline uint32_t full_representation_tag() const;
#ifdef DEBUG
inline uint32_t type() { return type_; }
inline uint32_t type() const { return type_; }
inline void invalidate() { valid_ = false; }
inline bool valid() { return valid_; }
inline bool valid() const { return valid_; }
#else
inline void invalidate() {}
#endif
@ -181,13 +181,13 @@ class String : public TorqueGeneratedString<String, Name> {
// SharedStringAccessGuard is not needed (i.e. on the main thread or on
// read-only strings).
template <typename Char>
inline const Char* GetChars(const DisallowGarbageCollection& no_gc);
inline const Char* GetChars(const DisallowGarbageCollection& no_gc) const;
// Get chars from sequential or external strings.
template <typename Char>
inline const Char* GetChars(
const DisallowGarbageCollection& no_gc,
const SharedStringAccessGuardIfNeeded& access_guard);
const SharedStringAccessGuardIfNeeded& access_guard) const;
// Returns the address of the character at an offset into this string.
// Requires: this->IsFlat()
@ -217,8 +217,8 @@ class String : public TorqueGeneratedString<String, Name> {
// to this method are not efficient unless the string is flat.
// If it is called from a background thread, the LocalIsolate version should
// be used.
V8_INLINE uint16_t Get(int index, Isolate* isolate = nullptr);
V8_INLINE uint16_t Get(int index, LocalIsolate* local_isolate);
V8_INLINE uint16_t Get(int index, Isolate* isolate = nullptr) const;
V8_INLINE uint16_t Get(int index, LocalIsolate* local_isolate) const;
// ES6 section 7.1.3.1 ToNumber Applied to the String Type
static Handle<Object> ToNumber(Isolate* isolate, Handle<String> subject);
@ -253,7 +253,7 @@ class String : public TorqueGeneratedString<String, Name> {
// Returns the parent of a sliced string or first part of a flat cons string.
// Requires: StringShape(this).IsIndirect() && this->IsFlat()
inline String GetUnderlying();
inline String GetUnderlying() const;
// String relational comparison, implemented according to ES6 section 7.2.11
// Abstract Relational Comparison (step 5): The comparison of Strings uses a
@ -314,7 +314,7 @@ class String : public TorqueGeneratedString<String, Name> {
int start_index = 0);
// String equality operations.
inline bool Equals(String other);
inline bool Equals(String other) const;
inline static bool Equals(Isolate* isolate, Handle<String> one,
Handle<String> two);
@ -412,7 +412,7 @@ class String : public TorqueGeneratedString<String, Name> {
DECL_PRINTER(String)
DECL_VERIFIER(String)
inline bool IsFlat();
inline bool IsFlat() const;
// Max char codes.
static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
@ -534,7 +534,7 @@ class String : public TorqueGeneratedString<String, Name> {
friend class InternalizedStringKey;
// Implementation of the Get() public methods. Do not use directly.
V8_INLINE uint16_t GetImpl(int index);
V8_INLINE uint16_t GetImpl(int index) const;
// Implementation of the IsEqualTo() public methods. Do not use directly.
template <EqualityType kEqType, typename Char>
@ -547,7 +547,7 @@ class String : public TorqueGeneratedString<String, Name> {
// Slow case of String::Equals. This implementation works on any strings
// but it is most efficient on strings that are almost flat.
V8_EXPORT_PRIVATE bool SlowEquals(String other);
V8_EXPORT_PRIVATE bool SlowEquals(String other) const;
V8_EXPORT_PRIVATE static bool SlowEquals(Isolate* isolate, Handle<String> one,
Handle<String> two);
@ -619,20 +619,21 @@ class SeqOneByteString
using Char = uint8_t;
// Dispatched behavior.
inline uint8_t Get(int index);
inline uint8_t Get(int index) const;
inline void SeqOneByteStringSet(int index, uint16_t value);
// Get the address of the characters in this string.
inline Address GetCharsAddress();
inline Address GetCharsAddress() const;
// Get a pointer to the characters of the string. May only be called when a
// SharedStringAccessGuard is not needed (i.e. on the main thread or on
// read-only strings).
inline uint8_t* GetChars(const DisallowGarbageCollection& no_gc);
inline uint8_t* GetChars(const DisallowGarbageCollection& no_gc) const;
// Get a pointer to the characters of the string.
inline uint8_t* GetChars(const DisallowGarbageCollection& no_gc,
const SharedStringAccessGuardIfNeeded& access_guard);
inline uint8_t* GetChars(
const DisallowGarbageCollection& no_gc,
const SharedStringAccessGuardIfNeeded& access_guard) const;
// Clear uninitialized padding space. This ensures that the snapshot content
// is deterministic.
@ -664,20 +665,21 @@ class SeqTwoByteString
using Char = uint16_t;
// Dispatched behavior.
inline uint16_t Get(int index);
inline uint16_t Get(int index) const;
inline void SeqTwoByteStringSet(int index, uint16_t value);
// Get the address of the characters in this string.
inline Address GetCharsAddress();
inline Address GetCharsAddress() const;
// Get a pointer to the characters of the string. May only be called when a
// SharedStringAccessGuard is not needed (i.e. on the main thread or on
// read-only strings).
inline uc16* GetChars(const DisallowGarbageCollection& no_gc);
inline uc16* GetChars(const DisallowGarbageCollection& no_gc) const;
// Get a pointer to the characters of the string.
inline uc16* GetChars(const DisallowGarbageCollection& no_gc,
const SharedStringAccessGuardIfNeeded& access_guard);
inline uc16* GetChars(
const DisallowGarbageCollection& no_gc,
const SharedStringAccessGuardIfNeeded& access_guard) const;
// Clear uninitialized padding space. This ensures that the snapshot content
// is deterministic.
@ -720,7 +722,7 @@ class ConsString : public TorqueGeneratedConsString<ConsString, String> {
inline Object unchecked_second();
// Dispatched behavior.
V8_EXPORT_PRIVATE uint16_t Get(int index);
V8_EXPORT_PRIVATE uint16_t Get(int index) const;
// Minimum length for a cons string.
static const int kMinLength = 13;
@ -743,7 +745,7 @@ class ThinString : public TorqueGeneratedThinString<ThinString, String> {
public:
DECL_GETTER(unchecked_actual, HeapObject)
V8_EXPORT_PRIVATE uint16_t Get(int index);
V8_EXPORT_PRIVATE uint16_t Get(int index) const;
DECL_VERIFIER(ThinString)
@ -769,7 +771,7 @@ class SlicedString : public TorqueGeneratedSlicedString<SlicedString, String> {
inline void set_parent(String parent,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// Dispatched behavior.
V8_EXPORT_PRIVATE uint16_t Get(int index);
V8_EXPORT_PRIVATE uint16_t Get(int index) const;
// Minimum length for a sliced string.
static const int kMinLength = 13;
@ -848,10 +850,10 @@ class ExternalOneByteString : public ExternalString {
// which the pointer cache has to be refreshed.
inline void update_data_cache(Isolate* isolate);
inline const uint8_t* GetChars();
inline const uint8_t* GetChars() const;
// Dispatched behavior.
inline uint8_t Get(int index);
inline uint8_t Get(int index) const;
DECL_CAST(ExternalOneByteString)
@ -894,10 +896,10 @@ class ExternalTwoByteString : public ExternalString {
// which the pointer cache has to be refreshed.
inline void update_data_cache(Isolate* isolate);
inline const uint16_t* GetChars();
inline const uint16_t* GetChars() const;
// Dispatched behavior.
inline uint16_t Get(int index);
inline uint16_t Get(int index) const;
// For regexp code.
inline const uint16_t* ExternalTwoByteStringGetData(unsigned start);
@ -927,9 +929,9 @@ class V8_EXPORT_PRIVATE FlatStringReader : public Relocatable {
public:
FlatStringReader(Isolate* isolate, Handle<String> str);
void PostGarbageCollection() override;
inline uc32 Get(int index);
inline uc32 Get(int index) const;
template <typename Char>
inline Char Get(int index);
inline Char Get(int index) const;
int length() { return length_; }
private: