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

Side by Side Diff: src/mark-compact.cc

Issue 6902029: Add prototype transitions cache to Map. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « src/heap.cc ('k') | src/objects.h » ('j') | src/objects.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 marking_stack_.Push(map); 1070 marking_stack_.Push(map);
1071 } 1071 }
1072 } else { 1072 } else {
1073 SetMark(object); 1073 SetMark(object);
1074 marking_stack_.Push(object); 1074 marking_stack_.Push(object);
1075 } 1075 }
1076 } 1076 }
1077 1077
1078 1078
1079 void MarkCompactCollector::MarkMapContents(Map* map) { 1079 void MarkCompactCollector::MarkMapContents(Map* map) {
1080 // Mark prototype transitions array but don't push it into marking stack.
1081 // This will make references from it weak. We will clean dead prototype
1082 // transitions in ClearNonLiveTransitions.
1083 FixedArray* prototype_transitions = map->unchecked_prototype_transitions();
1084 if (!prototype_transitions->IsMarked()) SetMark(prototype_transitions);
1085
1080 MarkDescriptorArray(reinterpret_cast<DescriptorArray*>( 1086 MarkDescriptorArray(reinterpret_cast<DescriptorArray*>(
1081 *HeapObject::RawField(map, Map::kInstanceDescriptorsOffset))); 1087 *HeapObject::RawField(map, Map::kInstanceDescriptorsOffset)));
1082 1088
1083 // Mark the Object* fields of the Map. 1089 // Mark the Object* fields of the Map.
1084 // Since the descriptor array has been marked already, it is fine 1090 // Since the descriptor array has been marked already, it is fine
1085 // that one of these fields contains a pointer to it. 1091 // that one of these fields contains a pointer to it.
1086 Object** start_slot = HeapObject::RawField(map, 1092 Object** start_slot = HeapObject::RawField(map,
1087 Map::kPointerFieldsBeginOffset); 1093 Map::kPointerFieldsBeginOffset);
1088 1094
1089 Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset); 1095 Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset);
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
1487 1493
1488 // Safe to use during marking phase only. 1494 // Safe to use during marking phase only.
1489 bool MarkCompactCollector::SafeIsMap(HeapObject* object) { 1495 bool MarkCompactCollector::SafeIsMap(HeapObject* object) {
1490 MapWord metamap = object->map_word(); 1496 MapWord metamap = object->map_word();
1491 metamap.ClearMark(); 1497 metamap.ClearMark();
1492 return metamap.ToMap()->instance_type() == MAP_TYPE; 1498 return metamap.ToMap()->instance_type() == MAP_TYPE;
1493 } 1499 }
1494 1500
1495 1501
1496 void MarkCompactCollector::ClearNonLiveTransitions() { 1502 void MarkCompactCollector::ClearNonLiveTransitions() {
1497 HeapObjectIterator map_iterator(heap() ->map_space(), &SizeOfMarkedObject); 1503 HeapObjectIterator map_iterator(heap()->map_space(), &SizeOfMarkedObject);
1498 // Iterate over the map space, setting map transitions that go from 1504 // Iterate over the map space, setting map transitions that go from
1499 // a marked map to an unmarked map to null transitions. At the same time, 1505 // a marked map to an unmarked map to null transitions. At the same time,
1500 // set all the prototype fields of maps back to their original value, 1506 // set all the prototype fields of maps back to their original value,
1501 // dropping the back pointers temporarily stored in the prototype field. 1507 // dropping the back pointers temporarily stored in the prototype field.
1502 // Setting the prototype field requires following the linked list of 1508 // Setting the prototype field requires following the linked list of
1503 // back pointers, reversing them all at once. This allows us to find 1509 // back pointers, reversing them all at once. This allows us to find
1504 // those maps with map transitions that need to be nulled, and only 1510 // those maps with map transitions that need to be nulled, and only
1505 // scan the descriptor arrays of those maps, not all maps. 1511 // scan the descriptor arrays of those maps, not all maps.
1506 // All of these actions are carried out only on maps of JSObjects 1512 // All of these actions are carried out only on maps of JSObjects
1507 // and related subtypes. 1513 // and related subtypes.
1508 for (HeapObject* obj = map_iterator.next(); 1514 for (HeapObject* obj = map_iterator.next();
1509 obj != NULL; obj = map_iterator.next()) { 1515 obj != NULL; obj = map_iterator.next()) {
1510 Map* map = reinterpret_cast<Map*>(obj); 1516 Map* map = reinterpret_cast<Map*>(obj);
1511 if (!map->IsMarked() && map->IsByteArray()) continue; 1517 if (!map->IsMarked() && map->IsByteArray()) continue;
1512 1518
1513 ASSERT(SafeIsMap(map)); 1519 ASSERT(SafeIsMap(map));
1514 // Only JSObject and subtypes have map transitions and back pointers. 1520 // Only JSObject and subtypes have map transitions and back pointers.
1515 if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue; 1521 if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue;
1516 if (map->instance_type() > JS_FUNCTION_TYPE) continue; 1522 if (map->instance_type() > JS_FUNCTION_TYPE) continue;
1517 1523
1518 if (map->IsMarked() && map->attached_to_shared_function_info()) { 1524 if (map->IsMarked() && map->attached_to_shared_function_info()) {
1519 // This map is used for inobject slack tracking and has been detached 1525 // This map is used for inobject slack tracking and has been detached
1520 // from SharedFunctionInfo during the mark phase. 1526 // from SharedFunctionInfo during the mark phase.
1521 // Since it survived the GC, reattach it now. 1527 // Since it survived the GC, reattach it now.
1522 map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map); 1528 map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map);
1523 } 1529 }
1524 1530
1531 // Clear dead prototype transitions.
1532 FixedArray* prototype_transitions = map->unchecked_prototype_transitions();
1533 if (prototype_transitions->length() > 0) {
1534 int finger = Smi::cast(prototype_transitions->get(0))->value();
1535 int new_finger = 1;
1536 for (int i = 1; i < finger; i += 2) {
1537 Object* prototype = prototype_transitions->get(i);
1538 Object* cached_map = prototype_transitions->get(i + 1);
1539 if (HeapObject::cast(prototype)->IsMarked() &&
1540 HeapObject::cast(cached_map)->IsMarked()) {
1541 if (new_finger != i) {
1542 prototype_transitions->set_unchecked(heap_,
1543 new_finger,
1544 prototype,
1545 UPDATE_WRITE_BARRIER);
1546 prototype_transitions->set_unchecked(heap_,
1547 new_finger + 1,
1548 cached_map,
1549 SKIP_WRITE_BARRIER);
1550 }
1551 new_finger += 2;
1552 }
1553 }
1554
1555 // Fill slots that became free with undefined value.
1556 Object* undefined = heap()->raw_unchecked_undefined_value();
1557 for (int i = new_finger; i < finger; i++) {
1558 prototype_transitions->set_unchecked(heap_,
1559 i,
1560 undefined,
1561 SKIP_WRITE_BARRIER);
1562 }
1563 prototype_transitions->set_unchecked(0, Smi::FromInt(new_finger));
1564 }
1565
1525 // Follow the chain of back pointers to find the prototype. 1566 // Follow the chain of back pointers to find the prototype.
1526 Map* current = map; 1567 Map* current = map;
1527 while (SafeIsMap(current)) { 1568 while (SafeIsMap(current)) {
1528 current = reinterpret_cast<Map*>(current->prototype()); 1569 current = reinterpret_cast<Map*>(current->prototype());
1529 ASSERT(current->IsHeapObject()); 1570 ASSERT(current->IsHeapObject());
1530 } 1571 }
1531 Object* real_prototype = current; 1572 Object* real_prototype = current;
1532 1573
1533 // Follow back pointers, setting them to prototype, 1574 // Follow back pointers, setting them to prototype,
1534 // clearing map transitions when necessary. 1575 // clearing map transitions when necessary.
(...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after
3090 } 3131 }
3091 3132
3092 3133
3093 void MarkCompactCollector::Initialize() { 3134 void MarkCompactCollector::Initialize() {
3094 StaticPointersToNewGenUpdatingVisitor::Initialize(); 3135 StaticPointersToNewGenUpdatingVisitor::Initialize();
3095 StaticMarkingVisitor::Initialize(); 3136 StaticMarkingVisitor::Initialize();
3096 } 3137 }
3097 3138
3098 3139
3099 } } // namespace v8::internal 3140 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.cc ('k') | src/objects.h » ('j') | src/objects.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698