Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(581)

Side by Side Diff: src/runtime/runtime-debug.cc

Issue 1291043002: Debugger: remove duplicate heap iterations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@debuggerglobal
Patch Set: slight change Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.cc ('k') | src/runtime/runtime-liveedit.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/debug/debug.h" 8 #include "src/debug/debug.h"
9 #include "src/debug/debug-evaluate.h" 9 #include "src/debug/debug-evaluate.h"
10 #include "src/debug/debug-frames.h" 10 #include "src/debug/debug-frames.h"
(...skipping 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after
1353 } 1353 }
1354 1354
1355 // Return result as a JS array. 1355 // Return result as a JS array.
1356 Handle<JSObject> result = 1356 Handle<JSObject> result =
1357 isolate->factory()->NewJSObject(isolate->array_function()); 1357 isolate->factory()->NewJSObject(isolate->array_function());
1358 JSArray::SetContent(Handle<JSArray>::cast(result), instances); 1358 JSArray::SetContent(Handle<JSArray>::cast(result), instances);
1359 return *result; 1359 return *result;
1360 } 1360 }
1361 1361
1362 1362
1363 // Helper function used by Runtime_DebugReferencedBy below.
1364 static int DebugReferencedBy(HeapIterator* iterator, JSObject* target,
1365 Object* instance_filter, int max_references,
1366 FixedArray* instances, int instances_size,
1367 JSFunction* arguments_function) {
1368 Isolate* isolate = target->GetIsolate();
1369 SealHandleScope shs(isolate);
1370 DisallowHeapAllocation no_allocation;
1371
1372 // Iterate the heap.
1373 int count = 0;
1374 JSObject* last = NULL;
1375 HeapObject* heap_obj = NULL;
1376 while (((heap_obj = iterator->next()) != NULL) &&
1377 (max_references == 0 || count < max_references)) {
1378 // Only look at all JSObjects.
1379 if (heap_obj->IsJSObject()) {
1380 // Skip context extension objects and argument arrays as these are
1381 // checked in the context of functions using them.
1382 JSObject* obj = JSObject::cast(heap_obj);
1383 if (obj->IsJSContextExtensionObject() ||
1384 obj->map()->GetConstructor() == arguments_function) {
1385 continue;
1386 }
1387
1388 // Check if the JS object has a reference to the object looked for.
1389 if (obj->ReferencesObject(target)) {
1390 // Check instance filter if supplied. This is normally used to avoid
1391 // references from mirror objects (see Runtime_IsInPrototypeChain).
1392 if (!instance_filter->IsUndefined()) {
1393 for (PrototypeIterator iter(isolate, obj); !iter.IsAtEnd();
1394 iter.Advance()) {
1395 if (iter.GetCurrent() == instance_filter) {
1396 obj = NULL; // Don't add this object.
1397 break;
1398 }
1399 }
1400 }
1401
1402 // Do not expose the global object directly.
1403 if (obj->IsJSGlobalObject()) {
1404 obj = JSGlobalObject::cast(obj)->global_proxy();
1405 }
1406
1407 if (obj != NULL) {
1408 // Valid reference found add to instance array if supplied an update
1409 // count.
1410 if (instances != NULL && count < instances_size) {
1411 instances->set(count, obj);
1412 }
1413 last = obj;
1414 count++;
1415 }
1416 }
1417 }
1418 }
1419
1420 // Check for circular reference only. This can happen when the object is only
1421 // referenced from mirrors and has a circular reference in which case the
1422 // object is not really alive and would have been garbage collected if not
1423 // referenced from the mirror.
1424 if (count == 1 && last == target) {
1425 count = 0;
1426 }
1427
1428 // Return the number of referencing objects found.
1429 return count;
1430 }
1431
1432
1433 // Scan the heap for objects with direct references to an object 1363 // Scan the heap for objects with direct references to an object
1434 // args[0]: the object to find references to 1364 // args[0]: the object to find references to
1435 // args[1]: constructor function for instances to exclude (Mirror) 1365 // args[1]: constructor function for instances to exclude (Mirror)
1436 // args[2]: the the maximum number of objects to return 1366 // args[2]: the the maximum number of objects to return
1437 RUNTIME_FUNCTION(Runtime_DebugReferencedBy) { 1367 RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
1438 HandleScope scope(isolate); 1368 HandleScope scope(isolate);
1439 DCHECK(args.length() == 3); 1369 DCHECK(args.length() == 3);
1440
1441 // Check parameters.
1442 CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0); 1370 CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
1443 CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1); 1371 CONVERT_ARG_HANDLE_CHECKED(Object, filter, 1);
1444 RUNTIME_ASSERT(instance_filter->IsUndefined() || 1372 RUNTIME_ASSERT(filter->IsUndefined() || filter->IsJSObject());
1445 instance_filter->IsJSObject());
1446 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); 1373 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
1447 RUNTIME_ASSERT(max_references >= 0); 1374 RUNTIME_ASSERT(max_references >= 0);
1448 1375
1449 1376 List<Handle<JSObject> > instances;
1450 // Get the constructor function for context extension and arguments array.
1451 Handle<JSFunction> arguments_function(
1452 JSFunction::cast(isolate->sloppy_arguments_map()->GetConstructor()));
1453
1454 // Get the number of referencing objects.
1455 int count;
1456 // First perform a full GC in order to avoid dead objects and to make the heap
1457 // iterable.
1458 Heap* heap = isolate->heap(); 1377 Heap* heap = isolate->heap();
1459 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
1460 { 1378 {
1461 HeapIterator heap_iterator(heap); 1379 HeapIterator iterator(heap, HeapIterator::kFilterUnreachable);
1462 count = DebugReferencedBy(&heap_iterator, *target, *instance_filter, 1380 // Get the constructor function for context extension and arguments array.
1463 max_references, NULL, 0, *arguments_function); 1381 Object* arguments_fun = isolate->sloppy_arguments_map()->GetConstructor();
1382 HeapObject* heap_obj;
1383 while ((heap_obj = iterator.next())) {
1384 if (!heap_obj->IsJSObject()) continue;
1385 JSObject* obj = JSObject::cast(heap_obj);
1386 if (obj->IsJSContextExtensionObject()) continue;
1387 if (obj->map()->GetConstructor() == arguments_fun) continue;
1388 if (!obj->ReferencesObject(*target)) continue;
1389 // Check filter if supplied. This is normally used to avoid
1390 // references from mirror objects.
1391 if (!filter->IsUndefined() &&
1392 obj->HasInPrototypeChain(isolate, *filter)) {
1393 continue;
1394 }
1395 if (obj->IsJSGlobalObject()) {
1396 obj = JSGlobalObject::cast(obj)->global_proxy();
1397 }
1398 instances.Add(Handle<JSObject>(obj));
1399 if (instances.length() == max_references) break;
1400 }
1401 // Iterate the rest of the heap to satisfy HeapIterator constraints.
1402 while (iterator.next()) {
1403 }
1464 } 1404 }
1465 1405
1466 // Allocate an array to hold the result. 1406 Handle<FixedArray> result;
1467 Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count); 1407 if (instances.length() == 1 && instances.last().is_identical_to(target)) {
1468 1408 // Check for circular reference only. This can happen when the object is
1469 // Fill the referencing objects. 1409 // only referenced from mirrors and has a circular reference in which case
1470 { 1410 // the object is not really alive and would have been garbage collected if
1471 HeapIterator heap_iterator(heap); 1411 // not referenced from the mirror.
1472 count = DebugReferencedBy(&heap_iterator, *target, *instance_filter, 1412 result = isolate->factory()->empty_fixed_array();
1473 max_references, *instances, count, 1413 } else {
1474 *arguments_function); 1414 result = isolate->factory()->NewFixedArray(instances.length());
1415 for (int i = 0; i < instances.length(); ++i) result->set(i, *instances[i]);
1475 } 1416 }
1476 1417 return *isolate->factory()->NewJSArrayWithElements(result);
1477 // Return result as JS array.
1478 Handle<JSFunction> constructor = isolate->array_function();
1479
1480 Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
1481 JSArray::SetContent(Handle<JSArray>::cast(result), instances);
1482 return *result;
1483 } 1418 }
1484 1419
1485 1420
1486 // Helper function used by Runtime_DebugConstructedBy below.
1487 static int DebugConstructedBy(HeapIterator* iterator, JSFunction* constructor,
1488 int max_references, FixedArray* instances,
1489 int instances_size) {
1490 DisallowHeapAllocation no_allocation;
1491
1492 // Iterate the heap.
1493 int count = 0;
1494 HeapObject* heap_obj = NULL;
1495 while (((heap_obj = iterator->next()) != NULL) &&
1496 (max_references == 0 || count < max_references)) {
1497 // Only look at all JSObjects.
1498 if (heap_obj->IsJSObject()) {
1499 JSObject* obj = JSObject::cast(heap_obj);
1500 if (obj->map()->GetConstructor() == constructor) {
1501 // Valid reference found add to instance array if supplied an update
1502 // count.
1503 if (instances != NULL && count < instances_size) {
1504 instances->set(count, obj);
1505 }
1506 count++;
1507 }
1508 }
1509 }
1510
1511 // Return the number of referencing objects found.
1512 return count;
1513 }
1514
1515
1516 // Scan the heap for objects constructed by a specific function. 1421 // Scan the heap for objects constructed by a specific function.
1517 // args[0]: the constructor to find instances of 1422 // args[0]: the constructor to find instances of
1518 // args[1]: the the maximum number of objects to return 1423 // args[1]: the the maximum number of objects to return
1519 RUNTIME_FUNCTION(Runtime_DebugConstructedBy) { 1424 RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
1520 HandleScope scope(isolate); 1425 HandleScope scope(isolate);
1521 DCHECK(args.length() == 2); 1426 DCHECK(args.length() == 2);
1522
1523
1524 // Check parameters.
1525 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0); 1427 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
1526 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); 1428 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
1527 RUNTIME_ASSERT(max_references >= 0); 1429 RUNTIME_ASSERT(max_references >= 0);
1528 1430
1529 // Get the number of referencing objects. 1431 List<Handle<JSObject> > instances;
1530 int count;
1531 // First perform a full GC in order to avoid dead objects and to make the heap
1532 // iterable.
1533 Heap* heap = isolate->heap(); 1432 Heap* heap = isolate->heap();
1534 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
1535 { 1433 {
1536 HeapIterator heap_iterator(heap); 1434 HeapIterator iterator(heap, HeapIterator::kFilterUnreachable);
1537 count = DebugConstructedBy(&heap_iterator, *constructor, max_references, 1435 HeapObject* heap_obj;
1538 NULL, 0); 1436 while ((heap_obj = iterator.next())) {
1437 if (!heap_obj->IsJSObject()) continue;
1438 JSObject* obj = JSObject::cast(heap_obj);
1439 if (obj->map()->GetConstructor() != *constructor) continue;
1440 instances.Add(Handle<JSObject>(obj));
1441 if (instances.length() == max_references) break;
1442 }
1443 // Iterate the rest of the heap to satisfy HeapIterator constraints.
1444 while (iterator.next()) {
1445 }
1539 } 1446 }
1540 1447
1541 // Allocate an array to hold the result. 1448 Handle<FixedArray> result =
1542 Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count); 1449 isolate->factory()->NewFixedArray(instances.length());
1543 1450 for (int i = 0; i < instances.length(); ++i) result->set(i, *instances[i]);
1544 // Fill the referencing objects. 1451 return *isolate->factory()->NewJSArrayWithElements(result);
1545 {
1546 HeapIterator heap_iterator2(heap);
1547 count = DebugConstructedBy(&heap_iterator2, *constructor, max_references,
1548 *instances, count);
1549 }
1550
1551 // Return result as JS array.
1552 Handle<JSFunction> array_function = isolate->array_function();
1553 Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
1554 JSArray::SetContent(Handle<JSArray>::cast(result), instances);
1555 return *result;
1556 } 1452 }
1557 1453
1558 1454
1559 // Find the effective prototype object as returned by __proto__. 1455 // Find the effective prototype object as returned by __proto__.
1560 // args[0]: the object to find the prototype for. 1456 // args[0]: the object to find the prototype for.
1561 RUNTIME_FUNCTION(Runtime_DebugGetPrototype) { 1457 RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
1562 HandleScope shs(isolate); 1458 HandleScope shs(isolate);
1563 DCHECK(args.length() == 1); 1459 DCHECK(args.length() == 1);
1564 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); 1460 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1565 return *Object::GetPrototypeSkipHiddenPrototypes(isolate, obj); 1461 return *Object::GetPrototypeSkipHiddenPrototypes(isolate, obj);
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
1827 return *isolate->factory()->undefined_value(); 1723 return *isolate->factory()->undefined_value();
1828 } 1724 }
1829 1725
1830 1726
1831 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { 1727 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) {
1832 UNIMPLEMENTED(); 1728 UNIMPLEMENTED();
1833 return NULL; 1729 return NULL;
1834 } 1730 }
1835 } // namespace internal 1731 } // namespace internal
1836 } // namespace v8 1732 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | src/runtime/runtime-liveedit.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698