| OLD | NEW |
| 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 1444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1455 | 1455 |
| 1456 private: | 1456 private: |
| 1457 template <int id> | 1457 template <int id> |
| 1458 static inline void TrackObjectStatsAndVisit(Map* map, HeapObject* obj); | 1458 static inline void TrackObjectStatsAndVisit(Map* map, HeapObject* obj); |
| 1459 | 1459 |
| 1460 // Code flushing support. | 1460 // Code flushing support. |
| 1461 | 1461 |
| 1462 static const int kRegExpCodeThreshold = 5; | 1462 static const int kRegExpCodeThreshold = 5; |
| 1463 | 1463 |
| 1464 static void UpdateRegExpCodeAgeAndFlush(Heap* heap, JSRegExp* re, | 1464 static void UpdateRegExpCodeAgeAndFlush(Heap* heap, JSRegExp* re, |
| 1465 bool is_ascii) { | 1465 bool is_one_byte) { |
| 1466 // Make sure that the fixed array is in fact initialized on the RegExp. | 1466 // Make sure that the fixed array is in fact initialized on the RegExp. |
| 1467 // We could potentially trigger a GC when initializing the RegExp. | 1467 // We could potentially trigger a GC when initializing the RegExp. |
| 1468 if (HeapObject::cast(re->data())->map()->instance_type() != | 1468 if (HeapObject::cast(re->data())->map()->instance_type() != |
| 1469 FIXED_ARRAY_TYPE) | 1469 FIXED_ARRAY_TYPE) |
| 1470 return; | 1470 return; |
| 1471 | 1471 |
| 1472 // Make sure this is a RegExp that actually contains code. | 1472 // Make sure this is a RegExp that actually contains code. |
| 1473 if (re->TypeTag() != JSRegExp::IRREGEXP) return; | 1473 if (re->TypeTag() != JSRegExp::IRREGEXP) return; |
| 1474 | 1474 |
| 1475 Object* code = re->DataAt(JSRegExp::code_index(is_ascii)); | 1475 Object* code = re->DataAt(JSRegExp::code_index(is_one_byte)); |
| 1476 if (!code->IsSmi() && | 1476 if (!code->IsSmi() && |
| 1477 HeapObject::cast(code)->map()->instance_type() == CODE_TYPE) { | 1477 HeapObject::cast(code)->map()->instance_type() == CODE_TYPE) { |
| 1478 // Save a copy that can be reinstated if we need the code again. | 1478 // Save a copy that can be reinstated if we need the code again. |
| 1479 re->SetDataAt(JSRegExp::saved_code_index(is_ascii), code); | 1479 re->SetDataAt(JSRegExp::saved_code_index(is_one_byte), code); |
| 1480 | 1480 |
| 1481 // Saving a copy might create a pointer into compaction candidate | 1481 // Saving a copy might create a pointer into compaction candidate |
| 1482 // that was not observed by marker. This might happen if JSRegExp data | 1482 // that was not observed by marker. This might happen if JSRegExp data |
| 1483 // was marked through the compilation cache before marker reached JSRegExp | 1483 // was marked through the compilation cache before marker reached JSRegExp |
| 1484 // object. | 1484 // object. |
| 1485 FixedArray* data = FixedArray::cast(re->data()); | 1485 FixedArray* data = FixedArray::cast(re->data()); |
| 1486 Object** slot = data->data_start() + JSRegExp::saved_code_index(is_ascii); | 1486 Object** slot = |
| 1487 data->data_start() + JSRegExp::saved_code_index(is_one_byte); |
| 1487 heap->mark_compact_collector()->RecordSlot(slot, slot, code); | 1488 heap->mark_compact_collector()->RecordSlot(slot, slot, code); |
| 1488 | 1489 |
| 1489 // Set a number in the 0-255 range to guarantee no smi overflow. | 1490 // Set a number in the 0-255 range to guarantee no smi overflow. |
| 1490 re->SetDataAt(JSRegExp::code_index(is_ascii), | 1491 re->SetDataAt(JSRegExp::code_index(is_one_byte), |
| 1491 Smi::FromInt(heap->sweep_generation() & 0xff)); | 1492 Smi::FromInt(heap->sweep_generation() & 0xff)); |
| 1492 } else if (code->IsSmi()) { | 1493 } else if (code->IsSmi()) { |
| 1493 int value = Smi::cast(code)->value(); | 1494 int value = Smi::cast(code)->value(); |
| 1494 // The regexp has not been compiled yet or there was a compilation error. | 1495 // The regexp has not been compiled yet or there was a compilation error. |
| 1495 if (value == JSRegExp::kUninitializedValue || | 1496 if (value == JSRegExp::kUninitializedValue || |
| 1496 value == JSRegExp::kCompilationErrorValue) { | 1497 value == JSRegExp::kCompilationErrorValue) { |
| 1497 return; | 1498 return; |
| 1498 } | 1499 } |
| 1499 | 1500 |
| 1500 // Check if we should flush now. | 1501 // Check if we should flush now. |
| 1501 if (value == ((heap->sweep_generation() - kRegExpCodeThreshold) & 0xff)) { | 1502 if (value == ((heap->sweep_generation() - kRegExpCodeThreshold) & 0xff)) { |
| 1502 re->SetDataAt(JSRegExp::code_index(is_ascii), | 1503 re->SetDataAt(JSRegExp::code_index(is_one_byte), |
| 1503 Smi::FromInt(JSRegExp::kUninitializedValue)); | 1504 Smi::FromInt(JSRegExp::kUninitializedValue)); |
| 1504 re->SetDataAt(JSRegExp::saved_code_index(is_ascii), | 1505 re->SetDataAt(JSRegExp::saved_code_index(is_one_byte), |
| 1505 Smi::FromInt(JSRegExp::kUninitializedValue)); | 1506 Smi::FromInt(JSRegExp::kUninitializedValue)); |
| 1506 } | 1507 } |
| 1507 } | 1508 } |
| 1508 } | 1509 } |
| 1509 | 1510 |
| 1510 | 1511 |
| 1511 // Works by setting the current sweep_generation (as a smi) in the | 1512 // Works by setting the current sweep_generation (as a smi) in the |
| 1512 // code object place in the data array of the RegExp and keeps a copy | 1513 // code object place in the data array of the RegExp and keeps a copy |
| 1513 // around that can be reinstated if we reuse the RegExp before flushing. | 1514 // around that can be reinstated if we reuse the RegExp before flushing. |
| 1514 // If we did not use the code for kRegExpCodeThreshold mark sweep GCs | 1515 // If we did not use the code for kRegExpCodeThreshold mark sweep GCs |
| 1515 // we flush the code. | 1516 // we flush the code. |
| 1516 static void VisitRegExpAndFlushCode(Map* map, HeapObject* object) { | 1517 static void VisitRegExpAndFlushCode(Map* map, HeapObject* object) { |
| 1517 Heap* heap = map->GetHeap(); | 1518 Heap* heap = map->GetHeap(); |
| 1518 MarkCompactCollector* collector = heap->mark_compact_collector(); | 1519 MarkCompactCollector* collector = heap->mark_compact_collector(); |
| 1519 if (!collector->is_code_flushing_enabled()) { | 1520 if (!collector->is_code_flushing_enabled()) { |
| 1520 VisitJSRegExp(map, object); | 1521 VisitJSRegExp(map, object); |
| 1521 return; | 1522 return; |
| 1522 } | 1523 } |
| 1523 JSRegExp* re = reinterpret_cast<JSRegExp*>(object); | 1524 JSRegExp* re = reinterpret_cast<JSRegExp*>(object); |
| 1524 // Flush code or set age on both ASCII and two byte code. | 1525 // Flush code or set age on both one byte and two byte code. |
| 1525 UpdateRegExpCodeAgeAndFlush(heap, re, true); | 1526 UpdateRegExpCodeAgeAndFlush(heap, re, true); |
| 1526 UpdateRegExpCodeAgeAndFlush(heap, re, false); | 1527 UpdateRegExpCodeAgeAndFlush(heap, re, false); |
| 1527 // Visit the fields of the RegExp, including the updated FixedArray. | 1528 // Visit the fields of the RegExp, including the updated FixedArray. |
| 1528 VisitJSRegExp(map, object); | 1529 VisitJSRegExp(map, object); |
| 1529 } | 1530 } |
| 1530 | 1531 |
| 1531 static VisitorDispatchTable<Callback> non_count_table_; | 1532 static VisitorDispatchTable<Callback> non_count_table_; |
| 1532 }; | 1533 }; |
| 1533 | 1534 |
| 1534 | 1535 |
| (...skipping 3018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4553 SlotsBuffer* buffer = *buffer_address; | 4554 SlotsBuffer* buffer = *buffer_address; |
| 4554 while (buffer != NULL) { | 4555 while (buffer != NULL) { |
| 4555 SlotsBuffer* next_buffer = buffer->next(); | 4556 SlotsBuffer* next_buffer = buffer->next(); |
| 4556 DeallocateBuffer(buffer); | 4557 DeallocateBuffer(buffer); |
| 4557 buffer = next_buffer; | 4558 buffer = next_buffer; |
| 4558 } | 4559 } |
| 4559 *buffer_address = NULL; | 4560 *buffer_address = NULL; |
| 4560 } | 4561 } |
| 4561 } | 4562 } |
| 4562 } // namespace v8::internal | 4563 } // namespace v8::internal |
| OLD | NEW |