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

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

Issue 988703002: Revert of Revert of Simplify and compact transitions storage (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix extra ';', again Created 5 years, 9 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/heap/mark-compact.h ('k') | src/heap/objects-visiting-inl.h » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/base/atomicops.h" 7 #include "src/base/atomicops.h"
8 #include "src/base/bits.h" 8 #include "src/base/bits.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/compilation-cache.h" 10 #include "src/compilation-cache.h"
(...skipping 1452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1463 Heap* heap = map->GetHeap(); 1463 Heap* heap = map->GetHeap();
1464 Map* map_obj = Map::cast(obj); 1464 Map* map_obj = Map::cast(obj);
1465 DCHECK(map->instance_type() == MAP_TYPE); 1465 DCHECK(map->instance_type() == MAP_TYPE);
1466 DescriptorArray* array = map_obj->instance_descriptors(); 1466 DescriptorArray* array = map_obj->instance_descriptors();
1467 if (map_obj->owns_descriptors() && 1467 if (map_obj->owns_descriptors() &&
1468 array != heap->empty_descriptor_array()) { 1468 array != heap->empty_descriptor_array()) {
1469 int fixed_array_size = array->Size(); 1469 int fixed_array_size = array->Size();
1470 heap->RecordFixedArraySubTypeStats(DESCRIPTOR_ARRAY_SUB_TYPE, 1470 heap->RecordFixedArraySubTypeStats(DESCRIPTOR_ARRAY_SUB_TYPE,
1471 fixed_array_size); 1471 fixed_array_size);
1472 } 1472 }
1473 if (map_obj->HasTransitionArray()) { 1473 if (TransitionArray::IsFullTransitionArray(map_obj->raw_transitions())) {
1474 int fixed_array_size = map_obj->transitions()->Size(); 1474 int fixed_array_size =
1475 TransitionArray::cast(map_obj->raw_transitions())->Size();
1475 heap->RecordFixedArraySubTypeStats(TRANSITION_ARRAY_SUB_TYPE, 1476 heap->RecordFixedArraySubTypeStats(TRANSITION_ARRAY_SUB_TYPE,
1476 fixed_array_size); 1477 fixed_array_size);
1477 } 1478 }
1478 if (map_obj->has_code_cache()) { 1479 if (map_obj->has_code_cache()) {
1479 CodeCache* cache = CodeCache::cast(map_obj->code_cache()); 1480 CodeCache* cache = CodeCache::cast(map_obj->code_cache());
1480 heap->RecordFixedArraySubTypeStats(MAP_CODE_CACHE_SUB_TYPE, 1481 heap->RecordFixedArraySubTypeStats(MAP_CODE_CACHE_SUB_TYPE,
1481 cache->default_cache()->Size()); 1482 cache->default_cache()->Size());
1482 if (!cache->normal_type_cache()->IsUndefined()) { 1483 if (!cache->normal_type_cache()->IsUndefined()) {
1483 heap->RecordFixedArraySubTypeStats( 1484 heap->RecordFixedArraySubTypeStats(
1484 MAP_CODE_CACHE_SUB_TYPE, 1485 MAP_CODE_CACHE_SUB_TYPE,
(...skipping 914 matching lines...) Expand 10 before | Expand all | Expand 10 after
2399 isolate(), DependentCode::kWeakCodeGroup); 2400 isolate(), DependentCode::kWeakCodeGroup);
2400 table->set(key_index, heap_->the_hole_value()); 2401 table->set(key_index, heap_->the_hole_value());
2401 table->set(value_index, heap_->the_hole_value()); 2402 table->set(value_index, heap_->the_hole_value());
2402 table->ElementRemoved(); 2403 table->ElementRemoved();
2403 } 2404 }
2404 } 2405 }
2405 } 2406 }
2406 2407
2407 2408
2408 void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) { 2409 void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) {
2409 int number_of_transitions = map->NumberOfProtoTransitions(); 2410 FixedArray* prototype_transitions =
2410 FixedArray* prototype_transitions = map->GetPrototypeTransitions(); 2411 TransitionArray::GetPrototypeTransitions(map);
2412 int number_of_transitions =
2413 TransitionArray::NumberOfPrototypeTransitions(prototype_transitions);
2411 2414
2412 const int header = Map::kProtoTransitionHeaderSize; 2415 const int header = TransitionArray::kProtoTransitionHeaderSize;
2413 int new_number_of_transitions = 0; 2416 int new_number_of_transitions = 0;
2414 for (int i = 0; i < number_of_transitions; i++) { 2417 for (int i = 0; i < number_of_transitions; i++) {
2415 Object* cached_map = prototype_transitions->get(header + i); 2418 Object* cached_map = prototype_transitions->get(header + i);
2416 if (IsMarked(cached_map)) { 2419 if (IsMarked(cached_map)) {
2417 if (new_number_of_transitions != i) { 2420 if (new_number_of_transitions != i) {
2418 prototype_transitions->set(header + new_number_of_transitions, 2421 prototype_transitions->set(header + new_number_of_transitions,
2419 cached_map, SKIP_WRITE_BARRIER); 2422 cached_map, SKIP_WRITE_BARRIER);
2420 } 2423 }
2421 new_number_of_transitions++; 2424 new_number_of_transitions++;
2422 } 2425 }
2423 } 2426 }
2424 2427
2425 if (new_number_of_transitions != number_of_transitions) { 2428 if (new_number_of_transitions != number_of_transitions) {
2426 map->SetNumberOfProtoTransitions(new_number_of_transitions); 2429 TransitionArray::SetNumberOfPrototypeTransitions(prototype_transitions,
2430 new_number_of_transitions);
2427 } 2431 }
2428 2432
2429 // Fill slots that became free with undefined value. 2433 // Fill slots that became free with undefined value.
2430 for (int i = new_number_of_transitions; i < number_of_transitions; i++) { 2434 for (int i = new_number_of_transitions; i < number_of_transitions; i++) {
2431 prototype_transitions->set_undefined(header + i); 2435 prototype_transitions->set_undefined(header + i);
2432 } 2436 }
2433 } 2437 }
2434 2438
2435 2439
2436 void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map, 2440 void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map,
2437 MarkBit map_mark) { 2441 MarkBit map_mark) {
2438 Object* potential_parent = map->GetBackPointer(); 2442 Object* potential_parent = map->GetBackPointer();
2439 if (!potential_parent->IsMap()) return; 2443 if (!potential_parent->IsMap()) return;
2440 Map* parent = Map::cast(potential_parent); 2444 Map* parent = Map::cast(potential_parent);
2441 2445
2442 // Follow back pointer, check whether we are dealing with a map transition 2446 // Follow back pointer, check whether we are dealing with a map transition
2443 // from a live map to a dead path and in case clear transitions of parent. 2447 // from a live map to a dead path and in case clear transitions of parent.
2444 bool current_is_alive = map_mark.Get(); 2448 bool current_is_alive = map_mark.Get();
2445 bool parent_is_alive = Marking::MarkBitFrom(parent).Get(); 2449 bool parent_is_alive = Marking::MarkBitFrom(parent).Get();
2446 if (!current_is_alive && parent_is_alive) { 2450 if (!current_is_alive && parent_is_alive) {
2447 ClearMapTransitions(parent); 2451 ClearMapTransitions(parent, map);
2448 } 2452 }
2449 } 2453 }
2450 2454
2451 2455
2452 // Clear a possible back pointer in case the transition leads to a dead map. 2456 // Clear a possible back pointer in case the transition leads to a dead map.
2453 // Return true in case a back pointer has been cleared and false otherwise. 2457 // Return true in case a back pointer has been cleared and false otherwise.
2454 bool MarkCompactCollector::ClearMapBackPointer(Map* target) { 2458 bool MarkCompactCollector::ClearMapBackPointer(Map* target) {
2455 if (Marking::MarkBitFrom(target).Get()) return false; 2459 if (Marking::MarkBitFrom(target).Get()) return false;
2456 target->SetBackPointer(heap_->undefined_value(), SKIP_WRITE_BARRIER); 2460 target->SetBackPointer(heap_->undefined_value(), SKIP_WRITE_BARRIER);
2457 return true; 2461 return true;
2458 } 2462 }
2459 2463
2460 2464
2461 void MarkCompactCollector::ClearMapTransitions(Map* map) { 2465 void MarkCompactCollector::ClearMapTransitions(Map* map, Map* dead_transition) {
2462 // If there are no transitions to be cleared, return. 2466 Object* transitions = map->raw_transitions();
2463 // TODO(verwaest) Should be an assert, otherwise back pointers are not 2467 int num_transitions = TransitionArray::NumberOfTransitions(transitions);
2464 // properly cleared.
2465 if (!map->HasTransitionArray()) return;
2466 2468
2467 TransitionArray* t = map->transitions(); 2469 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
2470 DescriptorArray* descriptors = map->instance_descriptors();
2471
2472 // A previously existing simple transition (stored in a WeakCell) may have
2473 // been cleared. Clear the useless cell pointer, and take ownership
2474 // of the descriptor array.
2475 if (transitions->IsWeakCell() && WeakCell::cast(transitions)->cleared()) {
2476 map->set_raw_transitions(Smi::FromInt(0));
2477 }
2478 if (num_transitions == 0 &&
2479 descriptors == dead_transition->instance_descriptors() &&
2480 number_of_own_descriptors > 0) {
2481 TrimDescriptorArray(map, descriptors, number_of_own_descriptors);
2482 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors);
2483 map->set_owns_descriptors(true);
2484 return;
2485 }
2468 2486
2469 int transition_index = 0; 2487 int transition_index = 0;
2470 2488
2471 DescriptorArray* descriptors = map->instance_descriptors();
2472 bool descriptors_owner_died = false; 2489 bool descriptors_owner_died = false;
2473 2490
2474 // Compact all live descriptors to the left. 2491 // Compact all live descriptors to the left.
2475 for (int i = 0; i < t->number_of_transitions(); ++i) { 2492 for (int i = 0; i < num_transitions; ++i) {
2476 Map* target = t->GetTarget(i); 2493 Map* target = TransitionArray::GetTarget(transitions, i);
2477 if (ClearMapBackPointer(target)) { 2494 if (ClearMapBackPointer(target)) {
2478 if (target->instance_descriptors() == descriptors) { 2495 if (target->instance_descriptors() == descriptors) {
2479 descriptors_owner_died = true; 2496 descriptors_owner_died = true;
2480 } 2497 }
2481 } else { 2498 } else {
2482 if (i != transition_index) { 2499 if (i != transition_index) {
2500 DCHECK(TransitionArray::IsFullTransitionArray(transitions));
2501 TransitionArray* t = TransitionArray::cast(transitions);
2483 Name* key = t->GetKey(i); 2502 Name* key = t->GetKey(i);
2484 t->SetKey(transition_index, key); 2503 t->SetKey(transition_index, key);
2485 Object** key_slot = t->GetKeySlot(transition_index); 2504 Object** key_slot = t->GetKeySlot(transition_index);
2486 RecordSlot(key_slot, key_slot, key); 2505 RecordSlot(key_slot, key_slot, key);
2487 // Target slots do not need to be recorded since maps are not compacted. 2506 // Target slots do not need to be recorded since maps are not compacted.
2488 t->SetTarget(transition_index, t->GetTarget(i)); 2507 t->SetTarget(transition_index, t->GetTarget(i));
2489 } 2508 }
2490 transition_index++; 2509 transition_index++;
2491 } 2510 }
2492 } 2511 }
2493 2512
2494 // If there are no transitions to be cleared, return. 2513 // If there are no transitions to be cleared, return.
2495 // TODO(verwaest) Should be an assert, otherwise back pointers are not 2514 // TODO(verwaest) Should be an assert, otherwise back pointers are not
2496 // properly cleared. 2515 // properly cleared.
2497 if (transition_index == t->number_of_transitions()) return; 2516 if (transition_index == num_transitions) return;
2498
2499 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
2500 2517
2501 if (descriptors_owner_died) { 2518 if (descriptors_owner_died) {
2502 if (number_of_own_descriptors > 0) { 2519 if (number_of_own_descriptors > 0) {
2503 TrimDescriptorArray(map, descriptors, number_of_own_descriptors); 2520 TrimDescriptorArray(map, descriptors, number_of_own_descriptors);
2504 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors); 2521 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors);
2505 map->set_owns_descriptors(true); 2522 map->set_owns_descriptors(true);
2506 } else { 2523 } else {
2507 DCHECK(descriptors == heap_->empty_descriptor_array()); 2524 DCHECK(descriptors == heap_->empty_descriptor_array());
2508 } 2525 }
2509 } 2526 }
2510 2527
2511 // Note that we never eliminate a transition array, though we might right-trim 2528 // Note that we never eliminate a transition array, though we might right-trim
2512 // such that number_of_transitions() == 0. If this assumption changes, 2529 // such that number_of_transitions() == 0. If this assumption changes,
2513 // TransitionArray::Insert() will need to deal with the case that a transition 2530 // TransitionArray::Insert() will need to deal with the case that a transition
2514 // array disappeared during GC. 2531 // array disappeared during GC.
2515 int trim = t->number_of_transitions_storage() - transition_index; 2532 int trim = TransitionArray::Capacity(transitions) - transition_index;
2516 if (trim > 0) { 2533 if (trim > 0) {
2534 // Non-full-TransitionArray cases can never reach this point.
2535 DCHECK(TransitionArray::IsFullTransitionArray(transitions));
2536 TransitionArray* t = TransitionArray::cast(transitions);
2517 heap_->RightTrimFixedArray<Heap::FROM_GC>( 2537 heap_->RightTrimFixedArray<Heap::FROM_GC>(
2518 t, t->IsSimpleTransition() ? trim 2538 t, trim * TransitionArray::kTransitionSize);
2519 : trim * TransitionArray::kTransitionSize);
2520 t->SetNumberOfTransitions(transition_index); 2539 t->SetNumberOfTransitions(transition_index);
2540 // The map still has a full transition array.
2541 DCHECK(TransitionArray::IsFullTransitionArray(map->raw_transitions()));
2521 } 2542 }
2522 DCHECK(map->HasTransitionArray());
2523 } 2543 }
2524 2544
2525 2545
2526 void MarkCompactCollector::TrimDescriptorArray(Map* map, 2546 void MarkCompactCollector::TrimDescriptorArray(Map* map,
2527 DescriptorArray* descriptors, 2547 DescriptorArray* descriptors,
2528 int number_of_own_descriptors) { 2548 int number_of_own_descriptors) {
2529 int number_of_descriptors = descriptors->number_of_descriptors_storage(); 2549 int number_of_descriptors = descriptors->number_of_descriptors_storage();
2530 int to_trim = number_of_descriptors - number_of_own_descriptors; 2550 int to_trim = number_of_descriptors - number_of_own_descriptors;
2531 if (to_trim == 0) return; 2551 if (to_trim == 0) return;
2532 2552
(...skipping 1691 matching lines...) Expand 10 before | Expand all | Expand 10 after
4224 4244
4225 { 4245 {
4226 GCTracer::Scope sweep_scope(heap()->tracer(), 4246 GCTracer::Scope sweep_scope(heap()->tracer(),
4227 GCTracer::Scope::MC_SWEEP_CELL); 4247 GCTracer::Scope::MC_SWEEP_CELL);
4228 SweepSpace(heap()->cell_space(), SEQUENTIAL_SWEEPING); 4248 SweepSpace(heap()->cell_space(), SEQUENTIAL_SWEEPING);
4229 SweepSpace(heap()->property_cell_space(), SEQUENTIAL_SWEEPING); 4249 SweepSpace(heap()->property_cell_space(), SEQUENTIAL_SWEEPING);
4230 } 4250 }
4231 4251
4232 EvacuateNewSpaceAndCandidates(); 4252 EvacuateNewSpaceAndCandidates();
4233 4253
4234 // ClearNonLiveTransitions depends on precise sweeping of map space to 4254 // ClearNonLiveReferences depends on precise sweeping of map space to
4235 // detect whether unmarked map became dead in this collection or in one 4255 // detect whether unmarked map became dead in this collection or in one
4236 // of the previous ones. 4256 // of the previous ones.
4237 { 4257 {
4238 GCTracer::Scope sweep_scope(heap()->tracer(), 4258 GCTracer::Scope sweep_scope(heap()->tracer(),
4239 GCTracer::Scope::MC_SWEEP_MAP); 4259 GCTracer::Scope::MC_SWEEP_MAP);
4240 SweepSpace(heap()->map_space(), SEQUENTIAL_SWEEPING); 4260 SweepSpace(heap()->map_space(), SEQUENTIAL_SWEEPING);
4241 } 4261 }
4242 4262
4243 // Deallocate unmarked objects and clear marked bits for marked objects. 4263 // Deallocate unmarked objects and clear marked bits for marked objects.
4244 heap_->lo_space()->FreeUnmarkedObjects(); 4264 heap_->lo_space()->FreeUnmarkedObjects();
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
4476 SlotsBuffer* buffer = *buffer_address; 4496 SlotsBuffer* buffer = *buffer_address;
4477 while (buffer != NULL) { 4497 while (buffer != NULL) {
4478 SlotsBuffer* next_buffer = buffer->next(); 4498 SlotsBuffer* next_buffer = buffer->next();
4479 DeallocateBuffer(buffer); 4499 DeallocateBuffer(buffer);
4480 buffer = next_buffer; 4500 buffer = next_buffer;
4481 } 4501 }
4482 *buffer_address = NULL; 4502 *buffer_address = NULL;
4483 } 4503 }
4484 } 4504 }
4485 } // namespace v8::internal 4505 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/objects-visiting-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698