Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 1477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1488 | 1488 |
| 1489 static void UpdateRegExpCodeAgeAndFlush(Heap* heap, | 1489 static void UpdateRegExpCodeAgeAndFlush(Heap* heap, |
| 1490 JSRegExp* re, | 1490 JSRegExp* re, |
| 1491 bool is_ascii) { | 1491 bool is_ascii) { |
| 1492 // Make sure that the fixed array is in fact initialized on the RegExp. | 1492 // Make sure that the fixed array is in fact initialized on the RegExp. |
| 1493 // We could potentially trigger a GC when initializing the RegExp. | 1493 // We could potentially trigger a GC when initializing the RegExp. |
| 1494 if (HeapObject::cast(re->data())->map()->instance_type() != | 1494 if (HeapObject::cast(re->data())->map()->instance_type() != |
| 1495 FIXED_ARRAY_TYPE) return; | 1495 FIXED_ARRAY_TYPE) return; |
| 1496 | 1496 |
| 1497 // Make sure this is a RegExp that actually contains code. | 1497 // Make sure this is a RegExp that actually contains code. |
| 1498 if (re->TypeTagUnchecked() != JSRegExp::IRREGEXP) return; | 1498 if (re->TypeTag() != JSRegExp::IRREGEXP) return; |
| 1499 | 1499 |
| 1500 Object* code = re->DataAtUnchecked(JSRegExp::code_index(is_ascii)); | 1500 Object* code = re->DataAt(JSRegExp::code_index(is_ascii)); |
| 1501 if (!code->IsSmi() && | 1501 if (!code->IsSmi() && |
| 1502 HeapObject::cast(code)->map()->instance_type() == CODE_TYPE) { | 1502 HeapObject::cast(code)->map()->instance_type() == CODE_TYPE) { |
| 1503 // Save a copy that can be reinstated if we need the code again. | 1503 // Save a copy that can be reinstated if we need the code again. |
| 1504 re->SetDataAtUnchecked(JSRegExp::saved_code_index(is_ascii), | 1504 re->SetDataAt(JSRegExp::saved_code_index(is_ascii), |
| 1505 code, | 1505 code); |
|
payer
2013/06/13 13:09:10
that fits in one line
Michael Starzinger
2013/06/13 13:59:09
Done.
| |
| 1506 heap); | |
| 1507 | 1506 |
| 1508 // Saving a copy might create a pointer into compaction candidate | 1507 // Saving a copy might create a pointer into compaction candidate |
| 1509 // that was not observed by marker. This might happen if JSRegExp data | 1508 // that was not observed by marker. This might happen if JSRegExp data |
| 1510 // was marked through the compilation cache before marker reached JSRegExp | 1509 // was marked through the compilation cache before marker reached JSRegExp |
| 1511 // object. | 1510 // object. |
| 1512 FixedArray* data = FixedArray::cast(re->data()); | 1511 FixedArray* data = FixedArray::cast(re->data()); |
| 1513 Object** slot = data->data_start() + JSRegExp::saved_code_index(is_ascii); | 1512 Object** slot = data->data_start() + JSRegExp::saved_code_index(is_ascii); |
| 1514 heap->mark_compact_collector()-> | 1513 heap->mark_compact_collector()-> |
| 1515 RecordSlot(slot, slot, code); | 1514 RecordSlot(slot, slot, code); |
| 1516 | 1515 |
| 1517 // Set a number in the 0-255 range to guarantee no smi overflow. | 1516 // Set a number in the 0-255 range to guarantee no smi overflow. |
| 1518 re->SetDataAtUnchecked(JSRegExp::code_index(is_ascii), | 1517 re->SetDataAt(JSRegExp::code_index(is_ascii), |
| 1519 Smi::FromInt(heap->sweep_generation() & 0xff), | 1518 Smi::FromInt(heap->sweep_generation() & 0xff)); |
| 1520 heap); | |
| 1521 } else if (code->IsSmi()) { | 1519 } else if (code->IsSmi()) { |
| 1522 int value = Smi::cast(code)->value(); | 1520 int value = Smi::cast(code)->value(); |
| 1523 // The regexp has not been compiled yet or there was a compilation error. | 1521 // The regexp has not been compiled yet or there was a compilation error. |
| 1524 if (value == JSRegExp::kUninitializedValue || | 1522 if (value == JSRegExp::kUninitializedValue || |
| 1525 value == JSRegExp::kCompilationErrorValue) { | 1523 value == JSRegExp::kCompilationErrorValue) { |
| 1526 return; | 1524 return; |
| 1527 } | 1525 } |
| 1528 | 1526 |
| 1529 // Check if we should flush now. | 1527 // Check if we should flush now. |
| 1530 if (value == ((heap->sweep_generation() - kRegExpCodeThreshold) & 0xff)) { | 1528 if (value == ((heap->sweep_generation() - kRegExpCodeThreshold) & 0xff)) { |
| 1531 re->SetDataAtUnchecked(JSRegExp::code_index(is_ascii), | 1529 re->SetDataAt(JSRegExp::code_index(is_ascii), |
| 1532 Smi::FromInt(JSRegExp::kUninitializedValue), | 1530 Smi::FromInt(JSRegExp::kUninitializedValue)); |
| 1533 heap); | 1531 re->SetDataAt(JSRegExp::saved_code_index(is_ascii), |
| 1534 re->SetDataAtUnchecked(JSRegExp::saved_code_index(is_ascii), | 1532 Smi::FromInt(JSRegExp::kUninitializedValue)); |
| 1535 Smi::FromInt(JSRegExp::kUninitializedValue), | |
| 1536 heap); | |
| 1537 } | 1533 } |
| 1538 } | 1534 } |
| 1539 } | 1535 } |
| 1540 | 1536 |
| 1541 | 1537 |
| 1542 // Works by setting the current sweep_generation (as a smi) in the | 1538 // Works by setting the current sweep_generation (as a smi) in the |
| 1543 // code object place in the data array of the RegExp and keeps a copy | 1539 // code object place in the data array of the RegExp and keeps a copy |
| 1544 // around that can be reinstated if we reuse the RegExp before flushing. | 1540 // around that can be reinstated if we reuse the RegExp before flushing. |
| 1545 // If we did not use the code for kRegExpCodeThreshold mark sweep GCs | 1541 // If we did not use the code for kRegExpCodeThreshold mark sweep GCs |
| 1546 // we flush the code. | 1542 // we flush the code. |
| (...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2441 if (map->IsFreeSpace()) continue; | 2437 if (map->IsFreeSpace()) continue; |
| 2442 | 2438 |
| 2443 ASSERT(map->IsMap()); | 2439 ASSERT(map->IsMap()); |
| 2444 if (!map->CanTransition()) continue; | 2440 if (!map->CanTransition()) continue; |
| 2445 | 2441 |
| 2446 if (map_mark.Get() && | 2442 if (map_mark.Get() && |
| 2447 map->attached_to_shared_function_info()) { | 2443 map->attached_to_shared_function_info()) { |
| 2448 // This map is used for inobject slack tracking and has been detached | 2444 // This map is used for inobject slack tracking and has been detached |
| 2449 // from SharedFunctionInfo during the mark phase. | 2445 // from SharedFunctionInfo during the mark phase. |
| 2450 // Since it survived the GC, reattach it now. | 2446 // Since it survived the GC, reattach it now. |
| 2451 map->unchecked_constructor()->shared()->AttachInitialMap(map); | 2447 JSFunction::cast(map->constructor())->shared()->AttachInitialMap(map); |
| 2452 } | 2448 } |
| 2453 | 2449 |
| 2454 ClearNonLivePrototypeTransitions(map); | 2450 ClearNonLivePrototypeTransitions(map); |
| 2455 ClearNonLiveMapTransitions(map, map_mark); | 2451 ClearNonLiveMapTransitions(map, map_mark); |
| 2456 | 2452 |
| 2457 if (map_mark.Get()) { | 2453 if (map_mark.Get()) { |
| 2458 ClearNonLiveDependentCode(map); | 2454 ClearNonLiveDependentCode(map); |
| 2459 } else { | 2455 } else { |
| 2460 ClearAndDeoptimizeDependentCode(map); | 2456 ClearAndDeoptimizeDependentCode(map); |
| 2461 } | 2457 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2472 const int proto_offset = header + Map::kProtoTransitionPrototypeOffset; | 2468 const int proto_offset = header + Map::kProtoTransitionPrototypeOffset; |
| 2473 const int map_offset = header + Map::kProtoTransitionMapOffset; | 2469 const int map_offset = header + Map::kProtoTransitionMapOffset; |
| 2474 const int step = Map::kProtoTransitionElementsPerEntry; | 2470 const int step = Map::kProtoTransitionElementsPerEntry; |
| 2475 for (int i = 0; i < number_of_transitions; i++) { | 2471 for (int i = 0; i < number_of_transitions; i++) { |
| 2476 Object* prototype = prototype_transitions->get(proto_offset + i * step); | 2472 Object* prototype = prototype_transitions->get(proto_offset + i * step); |
| 2477 Object* cached_map = prototype_transitions->get(map_offset + i * step); | 2473 Object* cached_map = prototype_transitions->get(map_offset + i * step); |
| 2478 if (IsMarked(prototype) && IsMarked(cached_map)) { | 2474 if (IsMarked(prototype) && IsMarked(cached_map)) { |
| 2479 int proto_index = proto_offset + new_number_of_transitions * step; | 2475 int proto_index = proto_offset + new_number_of_transitions * step; |
| 2480 int map_index = map_offset + new_number_of_transitions * step; | 2476 int map_index = map_offset + new_number_of_transitions * step; |
| 2481 if (new_number_of_transitions != i) { | 2477 if (new_number_of_transitions != i) { |
| 2482 prototype_transitions->set_unchecked( | 2478 prototype_transitions->set( |
| 2483 heap_, | |
| 2484 proto_index, | 2479 proto_index, |
| 2485 prototype, | 2480 prototype, |
| 2486 UPDATE_WRITE_BARRIER); | 2481 UPDATE_WRITE_BARRIER); |
| 2487 prototype_transitions->set_unchecked( | 2482 prototype_transitions->set( |
| 2488 heap_, | |
| 2489 map_index, | 2483 map_index, |
| 2490 cached_map, | 2484 cached_map, |
| 2491 SKIP_WRITE_BARRIER); | 2485 SKIP_WRITE_BARRIER); |
| 2492 } | 2486 } |
| 2493 Object** slot = | 2487 Object** slot = |
| 2494 HeapObject::RawField(prototype_transitions, | 2488 HeapObject::RawField(prototype_transitions, |
| 2495 FixedArray::OffsetOfElementAt(proto_index)); | 2489 FixedArray::OffsetOfElementAt(proto_index)); |
| 2496 RecordSlot(slot, slot, prototype); | 2490 RecordSlot(slot, slot, prototype); |
| 2497 new_number_of_transitions++; | 2491 new_number_of_transitions++; |
| 2498 } | 2492 } |
| (...skipping 1818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4317 while (buffer != NULL) { | 4311 while (buffer != NULL) { |
| 4318 SlotsBuffer* next_buffer = buffer->next(); | 4312 SlotsBuffer* next_buffer = buffer->next(); |
| 4319 DeallocateBuffer(buffer); | 4313 DeallocateBuffer(buffer); |
| 4320 buffer = next_buffer; | 4314 buffer = next_buffer; |
| 4321 } | 4315 } |
| 4322 *buffer_address = NULL; | 4316 *buffer_address = NULL; |
| 4323 } | 4317 } |
| 4324 | 4318 |
| 4325 | 4319 |
| 4326 } } // namespace v8::internal | 4320 } } // namespace v8::internal |
| OLD | NEW |