Handle AccessorPair struct in heap snapshot.
R=svenpanne@chromium.org, yurys@chromium.org Review URL: https://codereview.chromium.org/17616002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15320 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
eac9b2191b
commit
bd5fafd58a
@ -974,6 +974,8 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
|
||||
ExtractSharedFunctionInfoReferences(entry, SharedFunctionInfo::cast(obj));
|
||||
} else if (obj->IsScript()) {
|
||||
ExtractScriptReferences(entry, Script::cast(obj));
|
||||
} else if (obj->IsAccessorPair()) {
|
||||
ExtractAccessorPairReferences(entry, AccessorPair::cast(obj));
|
||||
} else if (obj->IsCodeCache()) {
|
||||
ExtractCodeCacheReferences(entry, CodeCache::cast(obj));
|
||||
} else if (obj->IsCode()) {
|
||||
@ -1242,6 +1244,15 @@ void V8HeapExplorer::ExtractScriptReferences(int entry, Script* script) {
|
||||
}
|
||||
|
||||
|
||||
void V8HeapExplorer::ExtractAccessorPairReferences(
|
||||
int entry, AccessorPair* accessors) {
|
||||
SetInternalReference(accessors, entry, "getter", accessors->getter(),
|
||||
AccessorPair::kGetterOffset);
|
||||
SetInternalReference(accessors, entry, "setter", accessors->setter(),
|
||||
AccessorPair::kSetterOffset);
|
||||
}
|
||||
|
||||
|
||||
void V8HeapExplorer::ExtractCodeCacheReferences(
|
||||
int entry, CodeCache* code_cache) {
|
||||
TagObject(code_cache->default_cache(), "(default code cache)");
|
||||
@ -1353,21 +1364,11 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
|
||||
js_obj, entry,
|
||||
descs->GetKey(i), descs->GetConstantFunction(i));
|
||||
break;
|
||||
case CALLBACKS: {
|
||||
Object* callback_obj = descs->GetValue(i);
|
||||
if (callback_obj->IsAccessorPair()) {
|
||||
AccessorPair* accessors = AccessorPair::cast(callback_obj);
|
||||
if (Object* getter = accessors->getter()) {
|
||||
SetPropertyReference(js_obj, entry, descs->GetKey(i),
|
||||
getter, "get-%s");
|
||||
}
|
||||
if (Object* setter = accessors->setter()) {
|
||||
SetPropertyReference(js_obj, entry, descs->GetKey(i),
|
||||
setter, "set-%s");
|
||||
}
|
||||
}
|
||||
case CALLBACKS:
|
||||
ExtractAccessorPairProperty(
|
||||
js_obj, entry,
|
||||
descs->GetKey(i), descs->GetValue(i));
|
||||
break;
|
||||
}
|
||||
case NORMAL: // only in slow mode
|
||||
case HANDLER: // only in lookup results, not in descriptors
|
||||
case INTERCEPTOR: // only in lookup results, not in descriptors
|
||||
@ -1389,15 +1390,32 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
|
||||
Object* value = target->IsPropertyCell()
|
||||
? PropertyCell::cast(target)->value()
|
||||
: target;
|
||||
if (k != heap_->hidden_string()) {
|
||||
SetPropertyReference(js_obj, entry, String::cast(k), value);
|
||||
} else {
|
||||
if (k == heap_->hidden_string()) {
|
||||
TagObject(value, "(hidden properties)");
|
||||
SetInternalReference(js_obj, entry, "hidden_properties", value);
|
||||
continue;
|
||||
}
|
||||
if (ExtractAccessorPairProperty(js_obj, entry, k, value)) continue;
|
||||
SetPropertyReference(js_obj, entry, String::cast(k), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool V8HeapExplorer::ExtractAccessorPairProperty(
|
||||
JSObject* js_obj, int entry, Object* key, Object* callback_obj) {
|
||||
if (!callback_obj->IsAccessorPair()) return false;
|
||||
AccessorPair* accessors = AccessorPair::cast(callback_obj);
|
||||
Object* getter = accessors->getter();
|
||||
if (!getter->IsOddball()) {
|
||||
SetPropertyReference(js_obj, entry, String::cast(key), getter, "get %s");
|
||||
}
|
||||
Object* setter = accessors->setter();
|
||||
if (!setter->IsOddball()) {
|
||||
SetPropertyReference(js_obj, entry, String::cast(key), setter, "set %s");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -462,12 +462,15 @@ class V8HeapExplorer : public HeapEntriesAllocator {
|
||||
void ExtractSharedFunctionInfoReferences(int entry,
|
||||
SharedFunctionInfo* shared);
|
||||
void ExtractScriptReferences(int entry, Script* script);
|
||||
void ExtractAccessorPairReferences(int entry, AccessorPair* accessors);
|
||||
void ExtractCodeCacheReferences(int entry, CodeCache* code_cache);
|
||||
void ExtractCodeReferences(int entry, Code* code);
|
||||
void ExtractCellReferences(int entry, Cell* cell);
|
||||
void ExtractPropertyCellReferences(int entry, PropertyCell* cell);
|
||||
void ExtractClosureReferences(JSObject* js_obj, int entry);
|
||||
void ExtractPropertyReferences(JSObject* js_obj, int entry);
|
||||
bool ExtractAccessorPairProperty(JSObject* js_obj, int entry,
|
||||
Object* key, Object* callback_obj);
|
||||
void ExtractElementReferences(JSObject* js_obj, int entry);
|
||||
void ExtractInternalReferences(JSObject* js_obj, int entry);
|
||||
bool IsEssentialObject(Object* object);
|
||||
|
@ -1507,7 +1507,7 @@ TEST(GetConstructorName) {
|
||||
}
|
||||
|
||||
|
||||
TEST(FastCaseGetter) {
|
||||
TEST(FastCaseAccessors) {
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
|
||||
@ -1520,21 +1520,58 @@ TEST(FastCaseGetter) {
|
||||
" return this.value_ = value;\n"
|
||||
"});\n");
|
||||
const v8::HeapSnapshot* snapshot =
|
||||
heap_profiler->TakeHeapSnapshot(v8_str("fastCaseGetter"));
|
||||
heap_profiler->TakeHeapSnapshot(v8_str("fastCaseAccessors"));
|
||||
|
||||
const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
|
||||
CHECK_NE(NULL, global);
|
||||
const v8::HeapGraphNode* obj1 =
|
||||
GetProperty(global, v8::HeapGraphEdge::kProperty, "obj1");
|
||||
CHECK_NE(NULL, obj1);
|
||||
const v8::HeapGraphNode* getterFunction =
|
||||
GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get-propWithGetter");
|
||||
CHECK_NE(NULL, getterFunction);
|
||||
const v8::HeapGraphNode* setterFunction =
|
||||
GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set-propWithSetter");
|
||||
CHECK_NE(NULL, setterFunction);
|
||||
const v8::HeapGraphNode* func;
|
||||
func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get propWithGetter");
|
||||
CHECK_NE(NULL, func);
|
||||
func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set propWithGetter");
|
||||
CHECK_EQ(NULL, func);
|
||||
func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set propWithSetter");
|
||||
CHECK_NE(NULL, func);
|
||||
func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get propWithSetter");
|
||||
CHECK_EQ(NULL, func);
|
||||
}
|
||||
|
||||
|
||||
TEST(SlowCaseAccessors) {
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
|
||||
|
||||
CompileRun("var obj1 = {};\n"
|
||||
"for (var i = 0; i < 100; ++i) obj1['z' + i] = {};"
|
||||
"obj1.__defineGetter__('propWithGetter', function Y() {\n"
|
||||
" return 42;\n"
|
||||
"});\n"
|
||||
"obj1.__defineSetter__('propWithSetter', function Z(value) {\n"
|
||||
" return this.value_ = value;\n"
|
||||
"});\n");
|
||||
const v8::HeapSnapshot* snapshot =
|
||||
heap_profiler->TakeHeapSnapshot(v8_str("slowCaseAccessors"));
|
||||
|
||||
const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
|
||||
CHECK_NE(NULL, global);
|
||||
const v8::HeapGraphNode* obj1 =
|
||||
GetProperty(global, v8::HeapGraphEdge::kProperty, "obj1");
|
||||
CHECK_NE(NULL, obj1);
|
||||
const v8::HeapGraphNode* func;
|
||||
func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get propWithGetter");
|
||||
CHECK_NE(NULL, func);
|
||||
func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set propWithGetter");
|
||||
CHECK_EQ(NULL, func);
|
||||
func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set propWithSetter");
|
||||
CHECK_NE(NULL, func);
|
||||
func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get propWithSetter");
|
||||
CHECK_EQ(NULL, func);
|
||||
}
|
||||
|
||||
|
||||
TEST(HiddenPropertiesFastCase) {
|
||||
LocalContext env;
|
||||
v8::HandleScope scope(env->GetIsolate());
|
||||
|
Loading…
Reference in New Issue
Block a user