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 "src/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 11971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11982 Isolate* isolate = shared->GetIsolate(); | 11982 Isolate* isolate = shared->GetIsolate(); |
11983 if (isolate->serializer_enabled()) return; | 11983 if (isolate->serializer_enabled()) return; |
11984 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); | 11984 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); |
11985 // Empty code maps are unsupported. | 11985 // Empty code maps are unsupported. |
11986 if (shared->OptimizedCodeMapIsCleared()) return; | 11986 if (shared->OptimizedCodeMapIsCleared()) return; |
11987 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(code); | 11987 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(code); |
11988 shared->optimized_code_map()->set(kSharedCodeIndex, *cell); | 11988 shared->optimized_code_map()->set(kSharedCodeIndex, *cell); |
11989 } | 11989 } |
11990 | 11990 |
11991 | 11991 |
11992 void SharedFunctionInfo::AddToOptimizedCodeMap( | 11992 void SharedFunctionInfo::AddToOptimizedCodeMapInternal( |
11993 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, | 11993 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, |
11994 Handle<HeapObject> code, Handle<LiteralsArray> literals, | 11994 Handle<HeapObject> code, Handle<LiteralsArray> literals, |
11995 BailoutId osr_ast_id) { | 11995 BailoutId osr_ast_id) { |
11996 Isolate* isolate = shared->GetIsolate(); | 11996 Isolate* isolate = shared->GetIsolate(); |
11997 if (isolate->serializer_enabled()) return; | 11997 if (isolate->serializer_enabled()) return; |
11998 DCHECK(*code == isolate->heap()->undefined_value() || | 11998 DCHECK(*code == isolate->heap()->undefined_value() || |
11999 !shared->SearchOptimizedCodeMap(*native_context, osr_ast_id).code); | 11999 !shared->SearchOptimizedCodeMap(*native_context, osr_ast_id).code); |
12000 DCHECK(*code == isolate->heap()->undefined_value() || | 12000 DCHECK(*code == isolate->heap()->undefined_value() || |
12001 Code::cast(*code)->kind() == Code::OPTIMIZED_FUNCTION); | 12001 Code::cast(*code)->kind() == Code::OPTIMIZED_FUNCTION); |
12002 DCHECK(native_context->IsNativeContext()); | 12002 DCHECK(native_context->IsNativeContext()); |
12003 STATIC_ASSERT(kEntryLength == 4); | 12003 STATIC_ASSERT(kEntryLength == 4); |
| 12004 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); |
12004 Handle<FixedArray> new_code_map; | 12005 Handle<FixedArray> new_code_map; |
12005 int entry; | 12006 int entry; |
12006 | 12007 |
12007 if (shared->OptimizedCodeMapIsCleared()) { | 12008 if (shared->OptimizedCodeMapIsCleared()) { |
12008 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); | 12009 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); |
12009 new_code_map->set(kSharedCodeIndex, *isolate->factory()->empty_weak_cell(), | 12010 new_code_map->set(kSharedCodeIndex, *isolate->factory()->empty_weak_cell(), |
12010 SKIP_WRITE_BARRIER); | 12011 SKIP_WRITE_BARRIER); |
12011 entry = kEntriesStart; | 12012 entry = kEntriesStart; |
12012 } else { | 12013 } else { |
12013 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); | |
12014 entry = shared->SearchOptimizedCodeMapEntry(*native_context, osr_ast_id); | 12014 entry = shared->SearchOptimizedCodeMapEntry(*native_context, osr_ast_id); |
12015 if (entry > kSharedCodeIndex) { | 12015 if (entry > kSharedCodeIndex) { |
12016 // Found an existing context-specific entry, it must not contain any code. | 12016 // Found an existing context-specific entry. If the user provided valid |
12017 DCHECK(WeakCell::cast(old_code_map->get(entry + kCachedCodeOffset)) | 12017 // code, it must not contain any code. |
| 12018 DCHECK(code->IsUndefined() || |
| 12019 WeakCell::cast(old_code_map->get(entry + kCachedCodeOffset)) |
12018 ->cleared()); | 12020 ->cleared()); |
| 12021 |
12019 // Just set the code and literals to the entry. | 12022 // Just set the code and literals to the entry. |
12020 Handle<WeakCell> code_cell = code->IsUndefined() | 12023 if (!code->IsUndefined()) { |
12021 ? isolate->factory()->empty_weak_cell() | 12024 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code); |
12022 : isolate->factory()->NewWeakCell(code); | 12025 old_code_map->set(entry + kCachedCodeOffset, *code_cell); |
| 12026 } |
12023 Handle<WeakCell> literals_cell = | 12027 Handle<WeakCell> literals_cell = |
12024 isolate->factory()->NewWeakCell(literals); | 12028 isolate->factory()->NewWeakCell(literals); |
12025 old_code_map->set(entry + kCachedCodeOffset, *code_cell); | |
12026 old_code_map->set(entry + kLiteralsOffset, *literals_cell); | 12029 old_code_map->set(entry + kLiteralsOffset, *literals_cell); |
12027 return; | 12030 return; |
12028 } | 12031 } |
12029 | 12032 |
12030 // Can we reuse an entry? | 12033 // Can we reuse an entry? |
12031 DCHECK(entry < kEntriesStart); | 12034 DCHECK(entry < kEntriesStart); |
12032 int length = old_code_map->length(); | 12035 int length = old_code_map->length(); |
12033 for (int i = kEntriesStart; i < length; i += kEntryLength) { | 12036 for (int i = kEntriesStart; i < length; i += kEntryLength) { |
12034 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) { | 12037 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) { |
12035 new_code_map = old_code_map; | 12038 new_code_map = old_code_map; |
12036 entry = i; | 12039 entry = i; |
12037 break; | 12040 break; |
12038 } | 12041 } |
12039 } | 12042 } |
12040 | 12043 |
12041 if (entry < kEntriesStart) { | 12044 if (entry < kEntriesStart) { |
12042 // Copy old optimized code map and append one new entry. | 12045 // Copy old optimized code map and append one new entry. |
12043 new_code_map = isolate->factory()->CopyFixedArrayAndGrow( | 12046 new_code_map = isolate->factory()->CopyFixedArrayAndGrow( |
12044 old_code_map, kEntryLength, TENURED); | 12047 old_code_map, kEntryLength, TENURED); |
12045 // TODO(mstarzinger): Temporary workaround. The allocation above might | 12048 // TODO(mstarzinger): Temporary workaround. The allocation above might |
12046 // have flushed the optimized code map and the copy we created is full of | 12049 // have flushed the optimized code map and the copy we created is full of |
12047 // holes. For now we just give up on adding the entry and pretend it got | 12050 // holes. For now we just give up on adding the entry and pretend it got |
12048 // flushed. | 12051 // flushed. |
12049 if (shared->OptimizedCodeMapIsCleared()) return; | 12052 if (shared->OptimizedCodeMapIsCleared()) return; |
12050 entry = old_code_map->length(); | 12053 entry = old_code_map->length(); |
12051 } | 12054 } |
12052 } | 12055 } |
12053 | 12056 |
12054 Handle<WeakCell> code_cell = code->IsUndefined() | 12057 WeakCell* context_cell = native_context->self_weak_cell(); |
12055 ? isolate->factory()->empty_weak_cell() | 12058 new_code_map->set(entry + kContextOffset, context_cell); |
12056 : isolate->factory()->NewWeakCell(code); | 12059 |
| 12060 bool created_new_map = !old_code_map.is_identical_to(new_code_map); |
| 12061 if (!code->IsUndefined() || created_new_map) { |
| 12062 Handle<WeakCell> code_cell = code->IsUndefined() |
| 12063 ? isolate->factory()->empty_weak_cell() |
| 12064 : isolate->factory()->NewWeakCell(code); |
| 12065 new_code_map->set(entry + kCachedCodeOffset, *code_cell); |
| 12066 } |
| 12067 |
12057 Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals); | 12068 Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals); |
12058 WeakCell* context_cell = native_context->self_weak_cell(); | 12069 new_code_map->set(entry + kLiteralsOffset, *literals_cell); |
12059 | 12070 |
12060 new_code_map->set(entry + kContextOffset, context_cell); | |
12061 new_code_map->set(entry + kCachedCodeOffset, *code_cell); | |
12062 new_code_map->set(entry + kLiteralsOffset, *literals_cell); | |
12063 new_code_map->set(entry + kOsrAstIdOffset, Smi::FromInt(osr_ast_id.ToInt())); | 12071 new_code_map->set(entry + kOsrAstIdOffset, Smi::FromInt(osr_ast_id.ToInt())); |
12064 | 12072 |
12065 #ifdef DEBUG | 12073 #ifdef DEBUG |
12066 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { | 12074 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { |
12067 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset)); | 12075 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset)); |
12068 DCHECK(cell->cleared() || cell->value()->IsNativeContext()); | 12076 DCHECK(cell->cleared() || cell->value()->IsNativeContext()); |
12069 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); | 12077 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); |
12070 DCHECK(cell->cleared() || | 12078 DCHECK(cell->cleared() || |
12071 (cell->value()->IsCode() && | 12079 (cell->value()->IsCode() && |
12072 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); | 12080 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); |
12073 cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset)); | 12081 cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset)); |
12074 DCHECK(cell->cleared() || cell->value()->IsFixedArray()); | 12082 DCHECK(cell->cleared() || cell->value()->IsFixedArray()); |
12075 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); | 12083 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); |
12076 } | 12084 } |
12077 #endif | 12085 #endif |
12078 | 12086 |
12079 FixedArray* old_code_map = shared->optimized_code_map(); | 12087 if (created_new_map) { |
12080 if (old_code_map != *new_code_map) { | |
12081 shared->set_optimized_code_map(*new_code_map); | 12088 shared->set_optimized_code_map(*new_code_map); |
12082 } | 12089 } |
12083 } | 12090 } |
12084 | 12091 |
12085 | 12092 |
12086 void SharedFunctionInfo::ClearOptimizedCodeMap() { | 12093 void SharedFunctionInfo::ClearOptimizedCodeMap() { |
12087 FixedArray* cleared_map = GetHeap()->cleared_optimized_code_map(); | 12094 FixedArray* cleared_map = GetHeap()->cleared_optimized_code_map(); |
12088 set_optimized_code_map(cleared_map, SKIP_WRITE_BARRIER); | 12095 set_optimized_code_map(cleared_map, SKIP_WRITE_BARRIER); |
12089 } | 12096 } |
12090 | 12097 |
(...skipping 7072 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19163 if (cell->value() != *new_value) { | 19170 if (cell->value() != *new_value) { |
19164 cell->set_value(*new_value); | 19171 cell->set_value(*new_value); |
19165 Isolate* isolate = cell->GetIsolate(); | 19172 Isolate* isolate = cell->GetIsolate(); |
19166 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19173 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
19167 isolate, DependentCode::kPropertyCellChangedGroup); | 19174 isolate, DependentCode::kPropertyCellChangedGroup); |
19168 } | 19175 } |
19169 } | 19176 } |
19170 | 19177 |
19171 } // namespace internal | 19178 } // namespace internal |
19172 } // namespace v8 | 19179 } // namespace v8 |
OLD | NEW |