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

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

Issue 9169045: Refactoring only: Extracted 2 methods from ClearNonLiveTransitions (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Incorporated online and offline review suggestions Created 8 years, 11 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/mark-compact.h ('k') | no next file » | 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 // 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 2292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2303 if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue; 2303 if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue;
2304 2304
2305 if (map_mark.Get() && 2305 if (map_mark.Get() &&
2306 map->attached_to_shared_function_info()) { 2306 map->attached_to_shared_function_info()) {
2307 // This map is used for inobject slack tracking and has been detached 2307 // This map is used for inobject slack tracking and has been detached
2308 // from SharedFunctionInfo during the mark phase. 2308 // from SharedFunctionInfo during the mark phase.
2309 // Since it survived the GC, reattach it now. 2309 // Since it survived the GC, reattach it now.
2310 map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map); 2310 map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map);
2311 } 2311 }
2312 2312
2313 // Clear dead prototype transitions. 2313 ClearNonLivePrototypeTransitions(map);
2314 int number_of_transitions = map->NumberOfProtoTransitions(); 2314 ClearNonLiveMapTransitions(map, map_mark);
2315 FixedArray* prototype_transitions = map->prototype_transitions();
2316
2317 int new_number_of_transitions = 0;
2318 const int header = Map::kProtoTransitionHeaderSize;
2319 const int proto_offset =
2320 header + Map::kProtoTransitionPrototypeOffset;
2321 const int map_offset = header + Map::kProtoTransitionMapOffset;
2322 const int step = Map::kProtoTransitionElementsPerEntry;
2323 for (int i = 0; i < number_of_transitions; i++) {
2324 Object* prototype = prototype_transitions->get(proto_offset + i * step);
2325 Object* cached_map = prototype_transitions->get(map_offset + i * step);
2326 if (IsMarked(prototype) && IsMarked(cached_map)) {
2327 int proto_index = proto_offset + new_number_of_transitions * step;
2328 int map_index = map_offset + new_number_of_transitions * step;
2329 if (new_number_of_transitions != i) {
2330 prototype_transitions->set_unchecked(
2331 heap_,
2332 proto_index,
2333 prototype,
2334 UPDATE_WRITE_BARRIER);
2335 prototype_transitions->set_unchecked(
2336 heap_,
2337 map_index,
2338 cached_map,
2339 SKIP_WRITE_BARRIER);
2340 }
2341 Object** slot =
2342 HeapObject::RawField(prototype_transitions,
2343 FixedArray::OffsetOfElementAt(proto_index));
2344 RecordSlot(slot, slot, prototype);
2345 new_number_of_transitions++;
2346 }
2347 }
2348
2349 if (new_number_of_transitions != number_of_transitions) {
2350 map->SetNumberOfProtoTransitions(new_number_of_transitions);
2351 }
2352
2353 // Fill slots that became free with undefined value.
2354 for (int i = new_number_of_transitions * step;
2355 i < number_of_transitions * step;
2356 i++) {
2357 prototype_transitions->set_undefined(heap_, header + i);
2358 }
2359
2360 // Follow the chain of back pointers to find the prototype.
2361 Map* current = map;
2362 while (current->IsMap()) {
2363 current = reinterpret_cast<Map*>(current->prototype());
2364 ASSERT(current->IsHeapObject());
2365 }
2366 Object* real_prototype = current;
2367
2368 // Follow back pointers, setting them to prototype,
2369 // clearing map transitions when necessary.
2370 current = map;
2371 bool on_dead_path = !map_mark.Get();
2372 Object* next;
2373 while (current->IsMap()) {
2374 next = current->prototype();
2375 // There should never be a dead map above a live map.
2376 MarkBit current_mark = Marking::MarkBitFrom(current);
2377 bool is_alive = current_mark.Get();
2378 ASSERT(on_dead_path || is_alive);
2379
2380 // A live map above a dead map indicates a dead transition.
2381 // This test will always be false on the first iteration.
2382 if (on_dead_path && is_alive) {
2383 on_dead_path = false;
2384 current->ClearNonLiveTransitions(heap(), real_prototype);
2385 }
2386 *HeapObject::RawField(current, Map::kPrototypeOffset) =
2387 real_prototype;
2388
2389 if (is_alive) {
2390 Object** slot = HeapObject::RawField(current, Map::kPrototypeOffset);
2391 RecordSlot(slot, slot, real_prototype);
2392 }
2393 current = reinterpret_cast<Map*>(next);
2394 }
2395 } 2315 }
2396 } 2316 }
2397 2317
2318
2319 void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) {
2320 int number_of_transitions = map->NumberOfProtoTransitions();
2321 FixedArray* prototype_transitions = map->prototype_transitions();
2322
2323 int new_number_of_transitions = 0;
2324 const int header = Map::kProtoTransitionHeaderSize;
2325 const int proto_offset = header + Map::kProtoTransitionPrototypeOffset;
2326 const int map_offset = header + Map::kProtoTransitionMapOffset;
2327 const int step = Map::kProtoTransitionElementsPerEntry;
2328 for (int i = 0; i < number_of_transitions; i++) {
2329 Object* prototype = prototype_transitions->get(proto_offset + i * step);
2330 Object* cached_map = prototype_transitions->get(map_offset + i * step);
2331 if (IsMarked(prototype) && IsMarked(cached_map)) {
2332 int proto_index = proto_offset + new_number_of_transitions * step;
2333 int map_index = map_offset + new_number_of_transitions * step;
2334 if (new_number_of_transitions != i) {
2335 prototype_transitions->set_unchecked(
2336 heap_,
2337 proto_index,
2338 prototype,
2339 UPDATE_WRITE_BARRIER);
2340 prototype_transitions->set_unchecked(
2341 heap_,
2342 map_index,
2343 cached_map,
2344 SKIP_WRITE_BARRIER);
2345 }
2346 Object** slot =
2347 HeapObject::RawField(prototype_transitions,
2348 FixedArray::OffsetOfElementAt(proto_index));
2349 RecordSlot(slot, slot, prototype);
2350 new_number_of_transitions++;
2351 }
2352 }
2353
2354 if (new_number_of_transitions != number_of_transitions) {
2355 map->SetNumberOfProtoTransitions(new_number_of_transitions);
2356 }
2357
2358 // Fill slots that became free with undefined value.
2359 for (int i = new_number_of_transitions * step;
2360 i < number_of_transitions * step;
2361 i++) {
2362 prototype_transitions->set_undefined(heap_, header + i);
2363 }
2364 }
2365
2366
2367 void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map,
2368 MarkBit map_mark) {
2369 // Follow the chain of back pointers to find the prototype.
2370 Map* real_prototype = map;
2371 while (real_prototype->IsMap()) {
2372 real_prototype = reinterpret_cast<Map*>(real_prototype->prototype());
2373 ASSERT(real_prototype->IsHeapObject());
2374 }
2375
2376 // Follow back pointers, setting them to prototype, clearing map transitions
2377 // when necessary.
2378 Map* current = map;
2379 bool current_is_alive = map_mark.Get();
2380 bool on_dead_path = !current_is_alive;
2381 while (current->IsMap()) {
2382 Object* next = current->prototype();
2383 // There should never be a dead map above a live map.
2384 ASSERT(on_dead_path || current_is_alive);
2385
2386 // A live map above a dead map indicates a dead transition. This test will
2387 // always be false on the first iteration.
2388 if (on_dead_path && current_is_alive) {
2389 on_dead_path = false;
2390 current->ClearNonLiveTransitions(heap(), real_prototype);
2391 }
2392
2393 Object** slot = HeapObject::RawField(current, Map::kPrototypeOffset);
2394 *slot = real_prototype;
2395 if (current_is_alive) RecordSlot(slot, slot, real_prototype);
2396
2397 current = reinterpret_cast<Map*>(next);
2398 current_is_alive = Marking::MarkBitFrom(current).Get();
2399 }
2400 }
2401
2398 2402
2399 void MarkCompactCollector::ProcessWeakMaps() { 2403 void MarkCompactCollector::ProcessWeakMaps() {
2400 Object* weak_map_obj = encountered_weak_maps(); 2404 Object* weak_map_obj = encountered_weak_maps();
2401 while (weak_map_obj != Smi::FromInt(0)) { 2405 while (weak_map_obj != Smi::FromInt(0)) {
2402 ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj))); 2406 ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj)));
2403 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj); 2407 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj);
2404 ObjectHashTable* table = ObjectHashTable::cast(weak_map->table()); 2408 ObjectHashTable* table = ObjectHashTable::cast(weak_map->table());
2405 for (int i = 0; i < table->Capacity(); i++) { 2409 for (int i = 0; i < table->Capacity(); i++) {
2406 if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) { 2410 if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) {
2407 Object* value = table->get(table->EntryToValueIndex(i)); 2411 Object* value = table->get(table->EntryToValueIndex(i));
(...skipping 1525 matching lines...) Expand 10 before | Expand all | Expand 10 after
3933 while (buffer != NULL) { 3937 while (buffer != NULL) {
3934 SlotsBuffer* next_buffer = buffer->next(); 3938 SlotsBuffer* next_buffer = buffer->next();
3935 DeallocateBuffer(buffer); 3939 DeallocateBuffer(buffer);
3936 buffer = next_buffer; 3940 buffer = next_buffer;
3937 } 3941 }
3938 *buffer_address = NULL; 3942 *buffer_address = NULL;
3939 } 3943 }
3940 3944
3941 3945
3942 } } // namespace v8::internal 3946 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698