Commit 6ba2b6da authored by Shu-yu Guo's avatar Shu-yu Guo Committed by V8 LUCI CQ

Plumb Isolate through GetConstructor and GetConstructorName

Currently the Isolate is gotten off of the object that the operation is
being performed on. Shared objects return the shared Isolate, which is
incorrect as it shouldn't be used to run JS, nor does it have
HandleScopes open. Plumb the executing Isolate through.

Bug: v8:12547
Change-Id: I428d21f5e6a9c51c8c7c4577395bf27c8706bdb4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3441033Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78963}
parent 52180d38
......@@ -4680,7 +4680,10 @@ MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
Local<String> v8::Object::GetConstructorName() {
auto self = Utils::OpenHandle(this);
i::Handle<i::String> name = i::JSReceiver::GetConstructorName(self);
// TODO(v8:12547): Support shared objects.
DCHECK(!self->InSharedHeap());
i::Handle<i::String> name =
i::JSReceiver::GetConstructorName(self->GetIsolate(), self);
return Utils::ToLocal(name);
}
......
......@@ -2724,7 +2724,7 @@ bool CompilationExceptionIsRangeError(Isolate* isolate, Handle<Object> obj) {
if (!obj->IsJSError(isolate)) return false;
Handle<JSReceiver> js_obj = Handle<JSReceiver>::cast(obj);
Handle<JSReceiver> constructor;
if (!JSReceiver::GetConstructor(js_obj).ToHandle(&constructor)) {
if (!JSReceiver::GetConstructor(isolate, js_obj).ToHandle(&constructor)) {
return false;
}
return *constructor == *isolate->range_error_function();
......
......@@ -438,8 +438,8 @@ class CircularStructureMessageBuilder {
private:
void AppendConstructorName(Handle<Object> object) {
builder_.AppendCharacter('\'');
Handle<String> constructor_name =
JSReceiver::GetConstructorName(Handle<JSReceiver>::cast(object));
Handle<String> constructor_name = JSReceiver::GetConstructorName(
builder_.isolate(), Handle<JSReceiver>::cast(object));
builder_.AppendString(constructor_name);
builder_.AppendCharacter('\'');
}
......
......@@ -471,7 +471,7 @@ Handle<Object> CallSiteInfo::GetTypeName(Handle<CallSiteInfo> info) {
if (receiver->IsJSProxy()) {
return isolate->factory()->Proxy_string();
}
return JSReceiver::GetConstructorName(receiver);
return JSReceiver::GetConstructorName(isolate, receiver);
}
#if V8_ENABLE_WEBASSEMBLY
......
......@@ -499,9 +499,7 @@ String JSReceiver::class_name() {
namespace {
std::pair<MaybeHandle<JSFunction>, Handle<String>> GetConstructorHelper(
Handle<JSReceiver> receiver) {
Isolate* isolate = receiver->GetIsolate();
Isolate* isolate, Handle<JSReceiver> receiver) {
// If the object was instantiated simply with base == new.target, the
// constructor on the map provides the most accurate name.
// Don't provide the info for prototypes, since their constructors are
......@@ -571,13 +569,14 @@ std::pair<MaybeHandle<JSFunction>, Handle<String>> GetConstructorHelper(
// static
MaybeHandle<JSFunction> JSReceiver::GetConstructor(
Handle<JSReceiver> receiver) {
return GetConstructorHelper(receiver).first;
Isolate* isolate, Handle<JSReceiver> receiver) {
return GetConstructorHelper(isolate, receiver).first;
}
// static
Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) {
return GetConstructorHelper(receiver).second;
Handle<String> JSReceiver::GetConstructorName(Isolate* isolate,
Handle<JSReceiver> receiver) {
return GetConstructorHelper(isolate, receiver).second;
}
MaybeHandle<NativeContext> JSReceiver::GetCreationContext() {
......
......@@ -228,13 +228,15 @@ class JSReceiver : public TorqueGeneratedJSReceiver<JSReceiver, HeapObject> {
// Returns the constructor (the function that was used to instantiate the
// object).
static MaybeHandle<JSFunction> GetConstructor(Handle<JSReceiver> receiver);
static MaybeHandle<JSFunction> GetConstructor(Isolate* isolate,
Handle<JSReceiver> receiver);
// Returns the constructor name (the (possibly inferred) name of the function
// that was used to instantiate the object), if any. If a FunctionTemplate is
// used to instantiate the object, the class_name of the FunctionTemplate is
// returned instead.
static Handle<String> GetConstructorName(Handle<JSReceiver> receiver);
static Handle<String> GetConstructorName(Isolate* isolate,
Handle<JSReceiver> receiver);
V8_EXPORT_PRIVATE MaybeHandle<NativeContext> GetCreationContext();
......
......@@ -778,7 +778,7 @@ void V8HeapExplorer::ExtractLocation(HeapEntry* entry, HeapObject object) {
} else if (object.IsJSObject()) {
JSObject obj = JSObject::cast(object);
JSFunction maybe_constructor = GetConstructor(obj);
JSFunction maybe_constructor = GetConstructor(heap_->isolate(), obj);
if (!maybe_constructor.is_null()) {
ExtractLocationForJSFunction(entry, maybe_constructor);
......@@ -810,7 +810,7 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject object) {
return AddEntry(object, HeapEntry::kRegExp, names_->GetName(re.source()));
} else if (object.IsJSObject()) {
const char* name = names_->GetName(
GetConstructorName(JSObject::cast(object)));
GetConstructorName(heap_->isolate(), JSObject::cast(object)));
if (object.IsJSGlobalObject()) {
auto it = global_object_tag_map_.find(JSGlobalObject::cast(object));
if (it != global_object_tag_map_.end()) {
......@@ -1760,24 +1760,23 @@ void V8HeapExplorer::ExtractInternalReferences(JSObject js_obj,
}
}
JSFunction V8HeapExplorer::GetConstructor(JSReceiver receiver) {
Isolate* isolate = receiver.GetIsolate();
JSFunction V8HeapExplorer::GetConstructor(Isolate* isolate,
JSReceiver receiver) {
DisallowGarbageCollection no_gc;
HandleScope scope(isolate);
MaybeHandle<JSFunction> maybe_constructor =
JSReceiver::GetConstructor(handle(receiver, isolate));
JSReceiver::GetConstructor(isolate, handle(receiver, isolate));
if (maybe_constructor.is_null()) return JSFunction();
return *maybe_constructor.ToHandleChecked();
}
String V8HeapExplorer::GetConstructorName(JSObject object) {
Isolate* isolate = object.GetIsolate();
String V8HeapExplorer::GetConstructorName(Isolate* isolate, JSObject object) {
if (object.IsJSFunction()) return ReadOnlyRoots(isolate).closure_string();
DisallowGarbageCollection no_gc;
HandleScope scope(isolate);
return *JSReceiver::GetConstructorName(handle(object, isolate));
return *JSReceiver::GetConstructorName(isolate, handle(object, isolate));
}
HeapEntry* V8HeapExplorer::GetEntry(Object obj) {
......
......@@ -391,8 +391,8 @@ class V8_EXPORT_PRIVATE V8HeapExplorer : public HeapEntriesAllocator {
const char* name,
size_t size);
static JSFunction GetConstructor(JSReceiver receiver);
static String GetConstructorName(JSObject object);
static JSFunction GetConstructor(Isolate* isolate, JSReceiver receiver);
static String GetConstructorName(Isolate* isolate, JSObject object);
private:
void MarkVisitedField(int offset);
......
......@@ -1158,7 +1158,7 @@ RUNTIME_FUNCTION(Runtime_CollectTypeProfile) {
Handle<String> type = Object::TypeOf(isolate, value);
if (value->IsJSReceiver()) {
Handle<JSReceiver> object = Handle<JSReceiver>::cast(value);
type = JSReceiver::GetConstructorName(object);
type = JSReceiver::GetConstructorName(isolate, object);
} else if (value->IsNull(isolate)) {
// typeof(null) is object. But it's more user-friendly to annotate
// null as type "null".
......
......@@ -297,6 +297,8 @@ class IncrementalStringBuilder {
IncrementalStringBuilder* builder_;
};
Isolate* isolate() { return isolate_; }
private:
Factory* factory() { return isolate_->factory(); }
......
......@@ -2106,6 +2106,7 @@ static int StringCmp(const char* ref, i::String act) {
TEST(GetConstructor) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate());
CompileRun(
"function Constructor1() {};\n"
......@@ -2128,42 +2129,43 @@ TEST(GetConstructor) {
.As<v8::Object>();
i::Handle<i::JSObject> js_obj1 =
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj1));
CHECK(!i::V8HeapExplorer::GetConstructor(*js_obj1).is_null());
CHECK(!i::V8HeapExplorer::GetConstructor(i_isolate, *js_obj1).is_null());
v8::Local<v8::Object> obj2 = js_global->Get(env.local(), v8_str("obj2"))
.ToLocalChecked()
.As<v8::Object>();
i::Handle<i::JSObject> js_obj2 =
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj2));
CHECK(!i::V8HeapExplorer::GetConstructor(*js_obj2).is_null());
CHECK(!i::V8HeapExplorer::GetConstructor(i_isolate, *js_obj2).is_null());
v8::Local<v8::Object> obj3 = js_global->Get(env.local(), v8_str("obj3"))
.ToLocalChecked()
.As<v8::Object>();
i::Handle<i::JSObject> js_obj3 =
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj3));
CHECK(!i::V8HeapExplorer::GetConstructor(*js_obj3).is_null());
CHECK(!i::V8HeapExplorer::GetConstructor(i_isolate, *js_obj3).is_null());
v8::Local<v8::Object> obj4 = js_global->Get(env.local(), v8_str("obj4"))
.ToLocalChecked()
.As<v8::Object>();
i::Handle<i::JSObject> js_obj4 =
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj4));
CHECK(!i::V8HeapExplorer::GetConstructor(*js_obj4).is_null());
CHECK(!i::V8HeapExplorer::GetConstructor(i_isolate, *js_obj4).is_null());
v8::Local<v8::Object> obj5 = js_global->Get(env.local(), v8_str("obj5"))
.ToLocalChecked()
.As<v8::Object>();
i::Handle<i::JSObject> js_obj5 =
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj5));
CHECK(i::V8HeapExplorer::GetConstructor(*js_obj5).is_null());
CHECK(i::V8HeapExplorer::GetConstructor(i_isolate, *js_obj5).is_null());
v8::Local<v8::Object> obj6 = js_global->Get(env.local(), v8_str("obj6"))
.ToLocalChecked()
.As<v8::Object>();
i::Handle<i::JSObject> js_obj6 =
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj6));
CHECK(i::V8HeapExplorer::GetConstructor(*js_obj6).is_null());
CHECK(i::V8HeapExplorer::GetConstructor(i_isolate, *js_obj6).is_null());
}
TEST(GetConstructorName) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate());
CompileRun(
"function Constructor1() {};\n"
......@@ -2186,43 +2188,43 @@ TEST(GetConstructorName) {
.As<v8::Object>();
i::Handle<i::JSObject> js_obj1 =
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj1));
CHECK_EQ(0, StringCmp(
"Constructor1", i::V8HeapExplorer::GetConstructorName(*js_obj1)));
CHECK_EQ(0, StringCmp("Constructor1", i::V8HeapExplorer::GetConstructorName(
i_isolate, *js_obj1)));
v8::Local<v8::Object> obj2 = js_global->Get(env.local(), v8_str("obj2"))
.ToLocalChecked()
.As<v8::Object>();
i::Handle<i::JSObject> js_obj2 =
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj2));
CHECK_EQ(0, StringCmp(
"Constructor2", i::V8HeapExplorer::GetConstructorName(*js_obj2)));
CHECK_EQ(0, StringCmp("Constructor2", i::V8HeapExplorer::GetConstructorName(
i_isolate, *js_obj2)));
v8::Local<v8::Object> obj3 = js_global->Get(env.local(), v8_str("obj3"))
.ToLocalChecked()
.As<v8::Object>();
i::Handle<i::JSObject> js_obj3 =
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj3));
CHECK_EQ(0, StringCmp("Constructor3",
i::V8HeapExplorer::GetConstructorName(*js_obj3)));
CHECK_EQ(0, StringCmp("Constructor3", i::V8HeapExplorer::GetConstructorName(
i_isolate, *js_obj3)));
v8::Local<v8::Object> obj4 = js_global->Get(env.local(), v8_str("obj4"))
.ToLocalChecked()
.As<v8::Object>();
i::Handle<i::JSObject> js_obj4 =
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj4));
CHECK_EQ(0, StringCmp("Constructor4",
i::V8HeapExplorer::GetConstructorName(*js_obj4)));
CHECK_EQ(0, StringCmp("Constructor4", i::V8HeapExplorer::GetConstructorName(
i_isolate, *js_obj4)));
v8::Local<v8::Object> obj5 = js_global->Get(env.local(), v8_str("obj5"))
.ToLocalChecked()
.As<v8::Object>();
i::Handle<i::JSObject> js_obj5 =
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj5));
CHECK_EQ(0, StringCmp(
"Object", i::V8HeapExplorer::GetConstructorName(*js_obj5)));
CHECK_EQ(0, StringCmp("Object", i::V8HeapExplorer::GetConstructorName(
i_isolate, *js_obj5)));
v8::Local<v8::Object> obj6 = js_global->Get(env.local(), v8_str("obj6"))
.ToLocalChecked()
.As<v8::Object>();
i::Handle<i::JSObject> js_obj6 =
i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj6));
CHECK_EQ(0, StringCmp(
"Object", i::V8HeapExplorer::GetConstructorName(*js_obj6)));
CHECK_EQ(0, StringCmp("Object", i::V8HeapExplorer::GetConstructorName(
i_isolate, *js_obj6)));
}
......
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