}
-int HeapSnapshotGenerator::GetGlobalSecurityToken() {
- return collection_->token_enumerator()->GetTokenId(
- Top::context()->global()->global_context()->security_token());
-}
-
-
-int HeapSnapshotGenerator::GetObjectSecurityToken(HeapObject* obj) {
- if (obj->IsGlobalContext()) {
- return collection_->token_enumerator()->GetTokenId(
- Context::cast(obj)->security_token());
- } else {
- return TokenEnumerator::kNoSecurityToken;
- }
-}
-
-
class IndexedReferencesExtractor : public ObjectVisitor {
public:
IndexedReferencesExtractor(HeapSnapshotGenerator* generator,
void HeapSnapshotGenerator::ExtractReferences(HeapObject* obj) {
// We need to reference JS global objects from snapshot's root.
- // We also need to only include global objects from the current
- // security context. And we don't want to add the global proxy,
- // as we don't have a special type for it.
+ // We use JSGlobalProxy because this is what embedder (e.g. browser)
+ // uses for the global object.
if (obj->IsJSGlobalProxy()) {
- int global_security_token = GetGlobalSecurityToken();
JSGlobalProxy* proxy = JSGlobalProxy::cast(obj);
- int object_security_token =
- collection_->token_enumerator()->GetTokenId(
- Context::cast(proxy->context())->security_token());
- if (object_security_token == TokenEnumerator::kNoSecurityToken
- || object_security_token == global_security_token) {
- SetRootReference(proxy->map()->prototype());
- }
+ SetRootReference(proxy->map()->prototype());
return;
}
class NamedEntriesDetector {
public:
NamedEntriesDetector()
- : has_A1(false), has_B1(false), has_C1(false),
- has_A2(false), has_B2(false), has_C2(false) {
+ : has_A2(false), has_B2(false), has_C2(false) {
}
void Apply(i::HeapEntry** entry_ptr) {
- if (IsReachableNodeWithName(*entry_ptr, "A1")) has_A1 = true;
- if (IsReachableNodeWithName(*entry_ptr, "B1")) has_B1 = true;
- if (IsReachableNodeWithName(*entry_ptr, "C1")) has_C1 = true;
if (IsReachableNodeWithName(*entry_ptr, "A2")) has_A2 = true;
if (IsReachableNodeWithName(*entry_ptr, "B2")) has_B2 = true;
if (IsReachableNodeWithName(*entry_ptr, "C2")) has_C2 = true;
return strcmp(name, entry->name()) == 0 && entry->painted_reachable();
}
- bool has_A1;
- bool has_B1;
- bool has_C1;
bool has_A2;
bool has_B2;
bool has_C2;
TEST(HeapSnapshot) {
v8::HandleScope scope;
- v8::Handle<v8::String> token1 = v8::String::New("token1");
- LocalContext env1;
- env1->SetSecurityToken(token1);
-
- CompileRun(
- "function A1() {}\n"
- "function B1(x) { this.x = x; }\n"
- "function C1(x) { this.x1 = x; this.x2 = x; }\n"
- "var a1 = new A1();\n"
- "var b1_1 = new B1(a1), b1_2 = new B1(a1);\n"
- "var c1 = new C1(a1);");
-
- v8::Handle<v8::String> token2 = v8::String::New("token2");
LocalContext env2;
- env2->SetSecurityToken(token2);
CompileRun(
"function A2() {}\n"
const_cast<i::HeapEntry*>(
reinterpret_cast<const i::HeapEntry*>(global_env2))->PaintAllReachable();
- // Verify, that JS global object of env2 doesn't have '..1'
- // properties, but has '..2' properties.
- CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a1"));
- CHECK_EQ(
- NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b1_1"));
- CHECK_EQ(
- NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b1_2"));
- CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "c1"));
+ // Verify, that JS global object of env2 has '..2' properties.
const v8::HeapGraphNode* a2_node =
GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a2");
CHECK_NE(NULL, a2_node);
// Verify that anything related to '[ABC]1' is not reachable.
NamedEntriesDetector det;
i_snapshot_env2->IterateEntries(&det);
- CHECK(!det.has_A1);
- CHECK(!det.has_B1);
- CHECK(!det.has_C1);
CHECK(det.has_A2);
CHECK(det.has_B2);
CHECK(det.has_C2);