| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <sstream> | 5 #include <sstream> |
| 6 | 6 |
| 7 #include "src/v8.h" | 7 #include "src/v8.h" |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
| (...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1395 HeapStringAllocator allocator; | 1395 HeapStringAllocator allocator; |
| 1396 StringStream accumulator(&allocator); | 1396 StringStream accumulator(&allocator); |
| 1397 PropertyCell::cast(this)->value()->ShortPrint(&accumulator); | 1397 PropertyCell::cast(this)->value()->ShortPrint(&accumulator); |
| 1398 os << accumulator.ToCString().get(); | 1398 os << accumulator.ToCString().get(); |
| 1399 break; | 1399 break; |
| 1400 } | 1400 } |
| 1401 case WEAK_CELL_TYPE: { | 1401 case WEAK_CELL_TYPE: { |
| 1402 os << "WeakCell for "; | 1402 os << "WeakCell for "; |
| 1403 HeapStringAllocator allocator; | 1403 HeapStringAllocator allocator; |
| 1404 StringStream accumulator(&allocator); | 1404 StringStream accumulator(&allocator); |
| 1405 WeakCell::cast(this)->value()->ShortPrint(&accumulator); | 1405 WeakCell::cast(this)->value(heap)->ShortPrint(&accumulator); |
| 1406 os << accumulator.ToCString().get(); | 1406 os << accumulator.ToCString().get(); |
| 1407 break; | 1407 break; |
| 1408 } | 1408 } |
| 1409 default: | 1409 default: |
| 1410 os << "<Other heap object (" << map()->instance_type() << ")>"; | 1410 os << "<Other heap object (" << map()->instance_type() << ")>"; |
| 1411 break; | 1411 break; |
| 1412 } | 1412 } |
| 1413 } | 1413 } |
| 1414 | 1414 |
| 1415 | 1415 |
| (...skipping 6624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8040 Handle<WeakFixedArray> WeakFixedArray::Add( | 8040 Handle<WeakFixedArray> WeakFixedArray::Add( |
| 8041 Handle<Object> maybe_array, Handle<HeapObject> value, | 8041 Handle<Object> maybe_array, Handle<HeapObject> value, |
| 8042 SearchForDuplicates search_for_duplicates) { | 8042 SearchForDuplicates search_for_duplicates) { |
| 8043 Handle<WeakFixedArray> array = | 8043 Handle<WeakFixedArray> array = |
| 8044 (maybe_array.is_null() || !maybe_array->IsWeakFixedArray()) | 8044 (maybe_array.is_null() || !maybe_array->IsWeakFixedArray()) |
| 8045 ? Allocate(value->GetIsolate(), 1, Handle<WeakFixedArray>::null()) | 8045 ? Allocate(value->GetIsolate(), 1, Handle<WeakFixedArray>::null()) |
| 8046 : Handle<WeakFixedArray>::cast(maybe_array); | 8046 : Handle<WeakFixedArray>::cast(maybe_array); |
| 8047 | 8047 |
| 8048 if (search_for_duplicates == kAddIfNotFound) { | 8048 if (search_for_duplicates == kAddIfNotFound) { |
| 8049 for (int i = 0; i < array->Length(); ++i) { | 8049 for (int i = 0; i < array->Length(); ++i) { |
| 8050 if (array->Get(i) == *value) return array; | 8050 if (array->EqualAt(i, *value)) return array; |
| 8051 } | 8051 } |
| 8052 } else { | 8052 } else { |
| 8053 #ifdef DEBUG | 8053 #ifdef DEBUG |
| 8054 for (int i = 0; i < array->Length(); ++i) { | 8054 for (int i = 0; i < array->Length(); ++i) { |
| 8055 DCHECK_NE(*value, array->Get(i)); | 8055 DCHECK(!array->EqualAt(i, *value)); |
| 8056 } | 8056 } |
| 8057 #endif | 8057 #endif |
| 8058 } | 8058 } |
| 8059 | 8059 |
| 8060 // Try to store the new entry if there's room. Optimize for consecutive | 8060 // Try to store the new entry if there's room. Optimize for consecutive |
| 8061 // accesses. | 8061 // accesses. |
| 8062 int first_index = array->last_used_index(); | 8062 int first_index = array->last_used_index(); |
| 8063 for (int i = first_index;;) { | 8063 for (int i = first_index;;) { |
| 8064 if (array->IsEmptySlot((i))) { | 8064 if (array->IsEmptySlot((i))) { |
| 8065 WeakFixedArray::Set(array, i, value); | 8065 WeakFixedArray::Set(array, i, value); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 8081 } | 8081 } |
| 8082 WeakFixedArray::Set(new_array, array->Length(), value); | 8082 WeakFixedArray::Set(new_array, array->Length(), value); |
| 8083 return new_array; | 8083 return new_array; |
| 8084 } | 8084 } |
| 8085 | 8085 |
| 8086 | 8086 |
| 8087 void WeakFixedArray::Remove(Handle<HeapObject> value) { | 8087 void WeakFixedArray::Remove(Handle<HeapObject> value) { |
| 8088 // Optimize for the most recently added element to be removed again. | 8088 // Optimize for the most recently added element to be removed again. |
| 8089 int first_index = last_used_index(); | 8089 int first_index = last_used_index(); |
| 8090 for (int i = first_index;;) { | 8090 for (int i = first_index;;) { |
| 8091 if (Get(i) == *value) { | 8091 if (EqualAt(i, *value)) { |
| 8092 clear(i); | 8092 clear(i); |
| 8093 // Users of WeakFixedArray should make sure that there are no duplicates, | 8093 // Users of WeakFixedArray should make sure that there are no duplicates, |
| 8094 // they can use Add(..., kAddIfNotFound) if necessary. | 8094 // they can use Add(..., kAddIfNotFound) if necessary. |
| 8095 return; | 8095 return; |
| 8096 } | 8096 } |
| 8097 i = (i + 1) % Length(); | 8097 i = (i + 1) % Length(); |
| 8098 if (i == first_index) break; | 8098 if (i == first_index) break; |
| 8099 } | 8099 } |
| 8100 } | 8100 } |
| 8101 | 8101 |
| (...skipping 2043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10145 return result; | 10145 return result; |
| 10146 } | 10146 } |
| 10147 | 10147 |
| 10148 | 10148 |
| 10149 Handle<JSObject> Script::GetWrapper(Handle<Script> script) { | 10149 Handle<JSObject> Script::GetWrapper(Handle<Script> script) { |
| 10150 Isolate* isolate = script->GetIsolate(); | 10150 Isolate* isolate = script->GetIsolate(); |
| 10151 if (!script->wrapper()->IsUndefined()) { | 10151 if (!script->wrapper()->IsUndefined()) { |
| 10152 Handle<WeakCell> cell(WeakCell::cast(script->wrapper())); | 10152 Handle<WeakCell> cell(WeakCell::cast(script->wrapper())); |
| 10153 if (!cell->cleared()) { | 10153 if (!cell->cleared()) { |
| 10154 // Return a handle for the existing script wrapper from the cache. | 10154 // Return a handle for the existing script wrapper from the cache. |
| 10155 return handle(JSObject::cast(cell->value())); | 10155 return handle(JSObject::cast(cell->value(isolate->heap()))); |
| 10156 } | 10156 } |
| 10157 // If we found an empty WeakCell, that means the script wrapper was | 10157 // If we found an empty WeakCell, that means the script wrapper was |
| 10158 // GCed. We are not notified directly of that, so we decrement here | 10158 // GCed. We are not notified directly of that, so we decrement here |
| 10159 // so that we at least don't count double for any given script. | 10159 // so that we at least don't count double for any given script. |
| 10160 isolate->counters()->script_wrappers()->Decrement(); | 10160 isolate->counters()->script_wrappers()->Decrement(); |
| 10161 } | 10161 } |
| 10162 // Construct a new script wrapper. | 10162 // Construct a new script wrapper. |
| 10163 isolate->counters()->script_wrappers()->Increment(); | 10163 isolate->counters()->script_wrappers()->Increment(); |
| 10164 Handle<JSFunction> constructor = isolate->script_function(); | 10164 Handle<JSFunction> constructor = isolate->script_function(); |
| 10165 Handle<JSValue> result = | 10165 Handle<JSValue> result = |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10648 } | 10648 } |
| 10649 | 10649 |
| 10650 | 10650 |
| 10651 Object* Code::FindNthObject(int n, Map* match_map) { | 10651 Object* Code::FindNthObject(int n, Map* match_map) { |
| 10652 DCHECK(is_inline_cache_stub()); | 10652 DCHECK(is_inline_cache_stub()); |
| 10653 DisallowHeapAllocation no_allocation; | 10653 DisallowHeapAllocation no_allocation; |
| 10654 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 10654 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
| 10655 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10655 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
| 10656 RelocInfo* info = it.rinfo(); | 10656 RelocInfo* info = it.rinfo(); |
| 10657 Object* object = info->target_object(); | 10657 Object* object = info->target_object(); |
| 10658 if (object->IsWeakCell()) object = WeakCell::cast(object)->value(); | 10658 Object* original_object = object; |
| 10659 if (object->IsWeakCell()) |
| 10660 object = WeakCell::cast(object)->ValueNoReadBarrier(); |
| 10659 if (object->IsHeapObject()) { | 10661 if (object->IsHeapObject()) { |
| 10660 if (HeapObject::cast(object)->map() == match_map) { | 10662 if (HeapObject::cast(object)->map() == match_map) { |
| 10661 if (--n == 0) return object; | 10663 if (--n == 0) { |
| 10664 WeakCell::TriggerReadBarrier(original_object); |
| 10665 return object; |
| 10666 } |
| 10662 } | 10667 } |
| 10663 } | 10668 } |
| 10664 } | 10669 } |
| 10665 return NULL; | 10670 return NULL; |
| 10666 } | 10671 } |
| 10667 | 10672 |
| 10668 | 10673 |
| 10669 AllocationSite* Code::FindFirstAllocationSite() { | 10674 AllocationSite* Code::FindFirstAllocationSite() { |
| 10670 Object* result = FindNthObject(1, GetHeap()->allocation_site_map()); | 10675 Object* result = FindNthObject(1, GetHeap()->allocation_site_map()); |
| 10671 return (result != NULL) ? AllocationSite::cast(result) : NULL; | 10676 return (result != NULL) ? AllocationSite::cast(result) : NULL; |
| 10672 } | 10677 } |
| 10673 | 10678 |
| 10674 | 10679 |
| 10675 Map* Code::FindFirstMap() { | 10680 Map* Code::FindFirstMap() { |
| 10676 Object* result = FindNthObject(1, GetHeap()->meta_map()); | 10681 Object* result = FindNthObject(1, GetHeap()->meta_map()); |
| 10677 return (result != NULL) ? Map::cast(result) : NULL; | 10682 if (result == NULL) return NULL; |
| 10683 Map* map = Map::cast(result); |
| 10684 if (map->instance_type() == WEAK_CELL_TYPE) { |
| 10685 // There may be reloc info with weak cell maps. These are just in use by |
| 10686 // the read barrier and are not useful to harvest for the type feedback. |
| 10687 map = reinterpret_cast<Map*>(FindNthObject(2, GetHeap()->meta_map())); |
| 10688 } |
| 10689 return map; |
| 10678 } | 10690 } |
| 10679 | 10691 |
| 10680 | 10692 |
| 10681 void Code::FindAndReplace(const FindAndReplacePattern& pattern) { | 10693 void Code::FindAndReplace(const FindAndReplacePattern& pattern) { |
| 10682 DCHECK(is_inline_cache_stub() || is_handler()); | 10694 DCHECK(is_inline_cache_stub() || is_handler()); |
| 10683 DisallowHeapAllocation no_allocation; | 10695 DisallowHeapAllocation no_allocation; |
| 10684 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 10696 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
| 10685 STATIC_ASSERT(FindAndReplacePattern::kMaxCount < 32); | 10697 STATIC_ASSERT(FindAndReplacePattern::kMaxCount < 32); |
| 10686 int current_pattern = 0; | 10698 int current_pattern = 0; |
| 10687 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10699 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
| 10688 RelocInfo* info = it.rinfo(); | 10700 RelocInfo* info = it.rinfo(); |
| 10689 Object* object = info->target_object(); | 10701 Object* object = info->target_object(); |
| 10702 Object* original_object = object; |
| 10703 if (object->IsWeakCell()) |
| 10704 object = WeakCell::cast(object)->ValueNoReadBarrier(); |
| 10690 if (object->IsHeapObject()) { | 10705 if (object->IsHeapObject()) { |
| 10691 if (object->IsWeakCell()) { | |
| 10692 object = HeapObject::cast(WeakCell::cast(object)->value()); | |
| 10693 } | |
| 10694 Map* map = HeapObject::cast(object)->map(); | 10706 Map* map = HeapObject::cast(object)->map(); |
| 10695 if (map == *pattern.find_[current_pattern]) { | 10707 if (map == *pattern.find_[current_pattern]) { |
| 10708 WeakCell::TriggerReadBarrier(original_object); |
| 10696 info->set_target_object(*pattern.replace_[current_pattern]); | 10709 info->set_target_object(*pattern.replace_[current_pattern]); |
| 10697 if (++current_pattern == pattern.count_) return; | 10710 if (++current_pattern == pattern.count_) return; |
| 10698 } | 10711 } |
| 10699 } | 10712 } |
| 10700 } | 10713 } |
| 10701 UNREACHABLE(); | 10714 UNREACHABLE(); |
| 10702 } | 10715 } |
| 10703 | 10716 |
| 10704 | 10717 |
| 10705 void Code::FindAllMaps(MapHandleList* maps) { | 10718 void Code::FindAllMaps(MapHandleList* maps) { |
| 10706 DCHECK(is_inline_cache_stub()); | 10719 DCHECK(is_inline_cache_stub()); |
| 10707 DisallowHeapAllocation no_allocation; | 10720 DisallowHeapAllocation no_allocation; |
| 10708 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 10721 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
| 10709 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10722 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
| 10710 RelocInfo* info = it.rinfo(); | 10723 RelocInfo* info = it.rinfo(); |
| 10711 Object* object = info->target_object(); | 10724 Object* object = info->target_object(); |
| 10712 if (object->IsWeakCell()) object = WeakCell::cast(object)->value(); | 10725 Object* original_object = object; |
| 10713 if (object->IsMap()) maps->Add(handle(Map::cast(object))); | 10726 if (object->IsWeakCell()) |
| 10727 object = WeakCell::cast(object)->ValueNoReadBarrier(); |
| 10728 if (object->IsMap()) { |
| 10729 Map* map = Map::cast(object); |
| 10730 // This 'if' filters out the weak cell map used by the read barrier. |
| 10731 if (map->instance_type() != WEAK_CELL_TYPE) { |
| 10732 WeakCell::TriggerReadBarrier(original_object); |
| 10733 maps->Add(handle(map)); |
| 10734 } |
| 10735 } |
| 10714 } | 10736 } |
| 10715 } | 10737 } |
| 10716 | 10738 |
| 10717 | 10739 |
| 10718 Code* Code::FindFirstHandler() { | 10740 Code* Code::FindFirstHandler() { |
| 10719 DCHECK(is_inline_cache_stub()); | 10741 DCHECK(is_inline_cache_stub()); |
| 10720 DisallowHeapAllocation no_allocation; | 10742 DisallowHeapAllocation no_allocation; |
| 10721 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | | 10743 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
| 10722 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 10744 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
| 10723 bool skip_next_handler = false; | 10745 bool skip_next_handler = false; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10769 | 10791 |
| 10770 MaybeHandle<Code> Code::FindHandlerForMap(Map* map) { | 10792 MaybeHandle<Code> Code::FindHandlerForMap(Map* map) { |
| 10771 DCHECK(is_inline_cache_stub()); | 10793 DCHECK(is_inline_cache_stub()); |
| 10772 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | | 10794 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
| 10773 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 10795 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
| 10774 bool return_next = false; | 10796 bool return_next = false; |
| 10775 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10797 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
| 10776 RelocInfo* info = it.rinfo(); | 10798 RelocInfo* info = it.rinfo(); |
| 10777 if (info->rmode() == RelocInfo::EMBEDDED_OBJECT) { | 10799 if (info->rmode() == RelocInfo::EMBEDDED_OBJECT) { |
| 10778 Object* object = info->target_object(); | 10800 Object* object = info->target_object(); |
| 10779 if (object->IsWeakCell()) object = WeakCell::cast(object)->value(); | 10801 Object* original_object = object; |
| 10780 if (object == map) return_next = true; | 10802 if (object->IsWeakCell()) |
| 10803 object = WeakCell::cast(object)->ValueNoReadBarrier(); |
| 10804 if (object == map) { |
| 10805 WeakCell::TriggerReadBarrier(original_object); |
| 10806 return_next = true; |
| 10807 } |
| 10781 } else if (return_next) { | 10808 } else if (return_next) { |
| 10782 Code* code = Code::GetCodeFromTargetAddress(info->target_address()); | 10809 Code* code = Code::GetCodeFromTargetAddress(info->target_address()); |
| 10783 DCHECK(code->kind() == Code::HANDLER); | 10810 DCHECK(code->kind() == Code::HANDLER); |
| 10784 return handle(code); | 10811 return handle(code); |
| 10785 } | 10812 } |
| 10786 } | 10813 } |
| 10787 return MaybeHandle<Code>(); | 10814 return MaybeHandle<Code>(); |
| 10788 } | 10815 } |
| 10789 | 10816 |
| 10790 | 10817 |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11070 ->SetWeakCellCache(*cell); | 11097 ->SetWeakCellCache(*cell); |
| 11071 return cell; | 11098 return cell; |
| 11072 } | 11099 } |
| 11073 | 11100 |
| 11074 | 11101 |
| 11075 WeakCell* Code::CachedWeakCell() { | 11102 WeakCell* Code::CachedWeakCell() { |
| 11076 DCHECK(kind() == OPTIMIZED_FUNCTION); | 11103 DCHECK(kind() == OPTIMIZED_FUNCTION); |
| 11077 Object* weak_cell_cache = | 11104 Object* weak_cell_cache = |
| 11078 DeoptimizationInputData::cast(deoptimization_data())->WeakCellCache(); | 11105 DeoptimizationInputData::cast(deoptimization_data())->WeakCellCache(); |
| 11079 if (weak_cell_cache->IsWeakCell()) { | 11106 if (weak_cell_cache->IsWeakCell()) { |
| 11080 DCHECK(this == WeakCell::cast(weak_cell_cache)->value()); | 11107 DCHECK(this == WeakCell::cast(weak_cell_cache)->ValueNoReadBarrier()); |
| 11081 return WeakCell::cast(weak_cell_cache); | 11108 return WeakCell::cast(weak_cell_cache); |
| 11082 } | 11109 } |
| 11083 return NULL; | 11110 return NULL; |
| 11084 } | 11111 } |
| 11085 | 11112 |
| 11086 | 11113 |
| 11087 #ifdef ENABLE_DISASSEMBLER | 11114 #ifdef ENABLE_DISASSEMBLER |
| 11088 | 11115 |
| 11089 void DeoptimizationInputData::DeoptimizationInputDataPrint( | 11116 void DeoptimizationInputData::DeoptimizationInputDataPrint( |
| 11090 std::ostream& os) { // NOLINT | 11117 std::ostream& os) { // NOLINT |
| (...skipping 5790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16881 Handle<DependentCode> codes = | 16908 Handle<DependentCode> codes = |
| 16882 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 16909 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
| 16883 DependentCode::kPropertyCellChangedGroup, | 16910 DependentCode::kPropertyCellChangedGroup, |
| 16884 info->object_wrapper()); | 16911 info->object_wrapper()); |
| 16885 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 16912 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 16886 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16913 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 16887 cell, info->zone()); | 16914 cell, info->zone()); |
| 16888 } | 16915 } |
| 16889 | 16916 |
| 16890 } } // namespace v8::internal | 16917 } } // namespace v8::internal |
| OLD | NEW |