Commit 9137e4a8 authored by yurys@chromium.org's avatar yurys@chromium.org

Expose a method for getting JSObject constructor name

Review URL: http://codereview.chromium.org/5256004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5890 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent be0f740d
...@@ -1539,6 +1539,11 @@ class Object : public Value { ...@@ -1539,6 +1539,11 @@ class Object : public Value {
*/ */
V8EXPORT Local<String> ObjectProtoToString(); V8EXPORT Local<String> ObjectProtoToString();
/**
* Returns the name of the function invoked as a constructor for this object.
*/
V8EXPORT Local<String> GetConstructorName();
/** Gets the number of internal fields for this Object. */ /** Gets the number of internal fields for this Object. */
V8EXPORT int InternalFieldCount(); V8EXPORT int InternalFieldCount();
/** Gets the value in an internal field. */ /** Gets the value in an internal field. */
......
...@@ -2451,6 +2451,15 @@ Local<String> v8::Object::ObjectProtoToString() { ...@@ -2451,6 +2451,15 @@ Local<String> v8::Object::ObjectProtoToString() {
} }
Local<String> v8::Object::GetConstructorName() {
ON_BAILOUT("v8::Object::GetConstructorName()", return Local<v8::String>());
ENTER_V8;
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::String> name(self->constructor_name());
return Utils::ToLocal(name);
}
bool v8::Object::Delete(v8::Handle<String> key) { bool v8::Object::Delete(v8::Handle<String> key) {
ON_BAILOUT("v8::Object::Delete()", return false); ON_BAILOUT("v8::Object::Delete()", return false);
ENTER_V8; ENTER_V8;
......
...@@ -69,7 +69,8 @@ class Clusterizer : public AllStatic { ...@@ -69,7 +69,8 @@ class Clusterizer : public AllStatic {
JSObjectsCluster Clusterizer::Clusterize(HeapObject* obj, bool fine_grain) { JSObjectsCluster Clusterizer::Clusterize(HeapObject* obj, bool fine_grain) {
if (obj->IsJSObject()) { if (obj->IsJSObject()) {
JSObject* js_obj = JSObject::cast(obj); JSObject* js_obj = JSObject::cast(obj);
String* constructor = JSObject::cast(js_obj)->constructor_name(); String* constructor = GetConstructorNameForHeapProfile(
JSObject::cast(js_obj));
// Differentiate Object and Array instances. // Differentiate Object and Array instances.
if (fine_grain && (constructor == Heap::Object_symbol() || if (fine_grain && (constructor == Heap::Object_symbol() ||
constructor == Heap::Array_symbol())) { constructor == Heap::Array_symbol())) {
...@@ -714,7 +715,7 @@ static void StackWeakReferenceCallback(Persistent<Value> object, ...@@ -714,7 +715,7 @@ static void StackWeakReferenceCallback(Persistent<Value> object,
static void PrintProducerStackTrace(Object* obj, void* trace) { static void PrintProducerStackTrace(Object* obj, void* trace) {
if (!obj->IsJSObject()) return; if (!obj->IsJSObject()) return;
String* constructor = JSObject::cast(obj)->constructor_name(); String* constructor = GetConstructorNameForHeapProfile(JSObject::cast(obj));
SmartPointer<char> s_name( SmartPointer<char> s_name(
constructor->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)); constructor->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL));
LOG(HeapSampleJSProducerEvent(GetConstructorName(*s_name), LOG(HeapSampleJSProducerEvent(GetConstructorName(*s_name),
...@@ -886,7 +887,8 @@ static JSObjectsCluster HeapObjectAsCluster(HeapObject* object) { ...@@ -886,7 +887,8 @@ static JSObjectsCluster HeapObjectAsCluster(HeapObject* object) {
return JSObjectsCluster(String::cast(object)); return JSObjectsCluster(String::cast(object));
} else { } else {
JSObject* js_obj = JSObject::cast(object); JSObject* js_obj = JSObject::cast(object);
String* constructor = JSObject::cast(js_obj)->constructor_name(); String* constructor = GetConstructorNameForHeapProfile(
JSObject::cast(js_obj));
return JSObjectsCluster(constructor, object); return JSObjectsCluster(constructor, object);
} }
} }
......
...@@ -1166,9 +1166,6 @@ String* JSObject::class_name() { ...@@ -1166,9 +1166,6 @@ String* JSObject::class_name() {
String* JSObject::constructor_name() { String* JSObject::constructor_name() {
if (IsJSFunction()) {
return Heap::closure_symbol();
}
if (map()->constructor()->IsJSFunction()) { if (map()->constructor()->IsJSFunction()) {
JSFunction* constructor = JSFunction::cast(map()->constructor()); JSFunction* constructor = JSFunction::cast(map()->constructor());
String* name = String::cast(constructor->shared()->name()); String* name = String::cast(constructor->shared()->name());
......
...@@ -1295,8 +1295,8 @@ HeapEntry* HeapSnapshot::AddEntry(HeapObject* object, ...@@ -1295,8 +1295,8 @@ HeapEntry* HeapSnapshot::AddEntry(HeapObject* object,
} else if (object->IsJSObject()) { } else if (object->IsJSObject()) {
return AddEntry(object, return AddEntry(object,
HeapEntry::kObject, HeapEntry::kObject,
collection_->GetName( collection_->GetName(GetConstructorNameForHeapProfile(
JSObject::cast(object)->constructor_name()), JSObject::cast(object))),
children_count, children_count,
retainers_count); retainers_count);
} else if (object->IsString()) { } else if (object->IsString()) {
...@@ -2769,6 +2769,12 @@ void HeapSnapshotJSONSerializer::SortHashMap( ...@@ -2769,6 +2769,12 @@ void HeapSnapshotJSONSerializer::SortHashMap(
sorted_entries->Sort(SortUsingEntryValue); sorted_entries->Sort(SortUsingEntryValue);
} }
String* GetConstructorNameForHeapProfile(JSObject* object) {
if (object->IsJSFunction()) return Heap::closure_symbol();
return object->constructor_name();
}
} } // namespace v8::internal } } // namespace v8::internal
#endif // ENABLE_LOGGING_AND_PROFILING #endif // ENABLE_LOGGING_AND_PROFILING
...@@ -1073,6 +1073,9 @@ class HeapSnapshotJSONSerializer { ...@@ -1073,6 +1073,9 @@ class HeapSnapshotJSONSerializer {
DISALLOW_COPY_AND_ASSIGN(HeapSnapshotJSONSerializer); DISALLOW_COPY_AND_ASSIGN(HeapSnapshotJSONSerializer);
}; };
String* GetConstructorNameForHeapProfile(JSObject* object);
} } // namespace v8::internal } } // namespace v8::internal
#endif // ENABLE_LOGGING_AND_PROFILING #endif // ENABLE_LOGGING_AND_PROFILING
......
...@@ -7819,6 +7819,31 @@ THREADED_TEST(ObjectProtoToString) { ...@@ -7819,6 +7819,31 @@ THREADED_TEST(ObjectProtoToString) {
} }
THREADED_TEST(ObjectGetConstructorName) {
v8::HandleScope scope;
LocalContext context;
v8_compile("function Parent() {};"
"function Child() {};"
"Child.prototype = new Parent();"
"var outer = { inner: function() { } };"
"var p = new Parent();"
"var c = new Child();"
"var x = new outer.inner();")->Run();
Local<v8::Value> p = context->Global()->Get(v8_str("p"));
CHECK(p->IsObject() && p->ToObject()->GetConstructorName()->Equals(
v8_str("Parent")));
Local<v8::Value> c = context->Global()->Get(v8_str("c"));
CHECK(c->IsObject() && c->ToObject()->GetConstructorName()->Equals(
v8_str("Child")));
Local<v8::Value> x = context->Global()->Get(v8_str("x"));
CHECK(x->IsObject() && x->ToObject()->GetConstructorName()->Equals(
v8_str("outer.inner")));
}
bool ApiTestFuzzer::fuzzing_ = false; bool ApiTestFuzzer::fuzzing_ = false;
i::Semaphore* ApiTestFuzzer::all_tests_done_= i::Semaphore* ApiTestFuzzer::all_tests_done_=
i::OS::CreateSemaphore(0); i::OS::CreateSemaphore(0);
......
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