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

Side by Side Diff: src/objects.cc

Issue 1433923002: Maintain a FixedArray for the optimized code map. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Created 5 years, 1 month 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
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 11244 matching lines...) Expand 10 before | Expand all | Expand 10 after
11255 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); 11255 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent));
11256 // No write barrier required, since the builtin is part of the root set. 11256 // No write barrier required, since the builtin is part of the root set.
11257 } 11257 }
11258 11258
11259 11259
11260 void SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap( 11260 void SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap(
11261 Handle<SharedFunctionInfo> shared, Handle<Code> code) { 11261 Handle<SharedFunctionInfo> shared, Handle<Code> code) {
11262 Isolate* isolate = shared->GetIsolate(); 11262 Isolate* isolate = shared->GetIsolate();
11263 if (isolate->serializer_enabled()) return; 11263 if (isolate->serializer_enabled()) return;
11264 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); 11264 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
11265 Handle<Object> value(shared->optimized_code_map(), isolate); 11265 // Empty code maps are unsupported.
11266 if (value->IsSmi()) return; // Empty code maps are unsupported. 11266 if (shared->OptimizedCodeMapIsCleared()) return;
11267 Handle<FixedArray> code_map = Handle<FixedArray>::cast(value); 11267 shared->optimized_code_map()->set(kSharedCodeIndex, *code);
11268 code_map->set(kSharedCodeIndex, *code);
11269 } 11268 }
11270 11269
11271 11270
11272 void SharedFunctionInfo::AddToOptimizedCodeMap( 11271 void SharedFunctionInfo::AddToOptimizedCodeMap(
11273 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, 11272 Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
11274 Handle<HeapObject> code, Handle<LiteralsArray> literals, 11273 Handle<HeapObject> code, Handle<LiteralsArray> literals,
11275 BailoutId osr_ast_id) { 11274 BailoutId osr_ast_id) {
11276 Isolate* isolate = shared->GetIsolate(); 11275 Isolate* isolate = shared->GetIsolate();
11277 if (isolate->serializer_enabled()) return; 11276 if (isolate->serializer_enabled()) return;
11278 DCHECK(*code == isolate->heap()->undefined_value() || 11277 DCHECK(*code == isolate->heap()->undefined_value() ||
11279 !shared->SearchOptimizedCodeMap(*native_context, osr_ast_id).code); 11278 !shared->SearchOptimizedCodeMap(*native_context, osr_ast_id).code);
11280 DCHECK(*code == isolate->heap()->undefined_value() || 11279 DCHECK(*code == isolate->heap()->undefined_value() ||
11281 Code::cast(*code)->kind() == Code::OPTIMIZED_FUNCTION); 11280 Code::cast(*code)->kind() == Code::OPTIMIZED_FUNCTION);
11282 DCHECK(native_context->IsNativeContext()); 11281 DCHECK(native_context->IsNativeContext());
11283 STATIC_ASSERT(kEntryLength == 4); 11282 STATIC_ASSERT(kEntryLength == 4);
11284 Handle<FixedArray> new_code_map; 11283 Handle<FixedArray> new_code_map;
11285 Handle<Object> value(shared->optimized_code_map(), isolate);
11286 int entry; 11284 int entry;
11287 if (value->IsSmi()) { 11285 if (shared->OptimizedCodeMapIsCleared()) {
11288 // No optimized code map.
11289 DCHECK_EQ(0, Smi::cast(*value)->value());
11290 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); 11286 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED);
11291 entry = kEntriesStart; 11287 entry = kEntriesStart;
11292 } else { 11288 } else {
11293 Handle<FixedArray> old_code_map = Handle<FixedArray>::cast(value); 11289 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate);
11294 entry = shared->SearchOptimizedCodeMapEntry(*native_context, osr_ast_id); 11290 entry = shared->SearchOptimizedCodeMapEntry(*native_context, osr_ast_id);
11295 if (entry > kSharedCodeIndex) { 11291 if (entry > kSharedCodeIndex) {
11296 // Found an existing context-specific entry, it must not contain any code. 11292 // Found an existing context-specific entry, it must not contain any code.
11297 DCHECK_EQ(isolate->heap()->undefined_value(), 11293 DCHECK_EQ(isolate->heap()->undefined_value(),
11298 old_code_map->get(entry + kCachedCodeOffset)); 11294 old_code_map->get(entry + kCachedCodeOffset));
11299 // Just set the code and literals to the entry. 11295 // Just set the code and literals to the entry.
11300 old_code_map->set(entry + kCachedCodeOffset, *code); 11296 old_code_map->set(entry + kCachedCodeOffset, *code);
11301 old_code_map->set(entry + kLiteralsOffset, *literals); 11297 old_code_map->set(entry + kLiteralsOffset, *literals);
11302 return; 11298 return;
11303 } 11299 }
11304 11300
11305 // Copy old optimized code map and append one new entry. 11301 // Copy old optimized code map and append one new entry.
11306 new_code_map = isolate->factory()->CopyFixedArrayAndGrow( 11302 new_code_map = isolate->factory()->CopyFixedArrayAndGrow(
11307 old_code_map, kEntryLength, TENURED); 11303 old_code_map, kEntryLength, TENURED);
11308 // TODO(mstarzinger): Temporary workaround. The allocation above might have 11304 // TODO(mstarzinger): Temporary workaround. The allocation above might have
11309 // flushed the optimized code map and the copy we created is full of holes. 11305 // flushed the optimized code map and the copy we created is full of holes.
11310 // For now we just give up on adding the entry and pretend it got flushed. 11306 // For now we just give up on adding the entry and pretend it got flushed.
11311 if (shared->optimized_code_map()->IsSmi()) return; 11307 if (shared->OptimizedCodeMapIsCleared()) return;
11312 entry = old_code_map->length(); 11308 entry = old_code_map->length();
11313 } 11309 }
11314 new_code_map->set(entry + kContextOffset, *native_context); 11310 new_code_map->set(entry + kContextOffset, *native_context);
11315 new_code_map->set(entry + kCachedCodeOffset, *code); 11311 new_code_map->set(entry + kCachedCodeOffset, *code);
11316 new_code_map->set(entry + kLiteralsOffset, *literals); 11312 new_code_map->set(entry + kLiteralsOffset, *literals);
11317 new_code_map->set(entry + kOsrAstIdOffset, Smi::FromInt(osr_ast_id.ToInt())); 11313 new_code_map->set(entry + kOsrAstIdOffset, Smi::FromInt(osr_ast_id.ToInt()));
11318 11314
11319 #ifdef DEBUG 11315 #ifdef DEBUG
11320 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { 11316 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
11321 DCHECK(new_code_map->get(i + kContextOffset)->IsNativeContext()); 11317 DCHECK(new_code_map->get(i + kContextOffset)->IsNativeContext());
11322 Object* code = new_code_map->get(i + kCachedCodeOffset); 11318 Object* code = new_code_map->get(i + kCachedCodeOffset);
11323 if (code != isolate->heap()->undefined_value()) { 11319 if (code != isolate->heap()->undefined_value()) {
11324 DCHECK(code->IsCode()); 11320 DCHECK(code->IsCode());
11325 DCHECK(Code::cast(code)->kind() == Code::OPTIMIZED_FUNCTION); 11321 DCHECK(Code::cast(code)->kind() == Code::OPTIMIZED_FUNCTION);
11326 } 11322 }
11327 DCHECK(new_code_map->get(i + kLiteralsOffset)->IsFixedArray()); 11323 DCHECK(new_code_map->get(i + kLiteralsOffset)->IsFixedArray());
11328 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); 11324 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi());
11329 } 11325 }
11330 #endif 11326 #endif
11331 11327
11332 // Zap any old optimized code map. 11328 // Zap any old optimized code map.
11333 if (!shared->optimized_code_map()->IsSmi()) { 11329 if (!shared->OptimizedCodeMapIsCleared()) {
11334 FixedArray* old_code_map = FixedArray::cast(shared->optimized_code_map()); 11330 FixedArray* old_code_map = shared->optimized_code_map();
11335 old_code_map->FillWithHoles(0, old_code_map->length()); 11331 old_code_map->FillWithHoles(0, old_code_map->length());
11336 } 11332 }
11337 11333
11338 shared->set_optimized_code_map(*new_code_map); 11334 shared->set_optimized_code_map(*new_code_map);
11339 } 11335 }
11340 11336
11341 11337
11342 void SharedFunctionInfo::ClearOptimizedCodeMap() { 11338 void SharedFunctionInfo::ClearOptimizedCodeMap() {
11343 // Zap any old optimized code map. 11339 // Zap any old optimized code map.
11344 if (!optimized_code_map()->IsSmi()) { 11340 if (!OptimizedCodeMapIsCleared()) {
11345 FixedArray* old_code_map = FixedArray::cast(optimized_code_map()); 11341 FixedArray* old_code_map = optimized_code_map();
11346 old_code_map->FillWithHoles(0, old_code_map->length()); 11342 old_code_map->FillWithHoles(0, old_code_map->length());
11347 } 11343 }
11348 11344
11349 set_optimized_code_map(Smi::FromInt(0)); 11345 FixedArray* cleared_map = GetHeap()->cleared_optimized_code_map();
11346 set_optimized_code_map(cleared_map, SKIP_WRITE_BARRIER);
11350 } 11347 }
11351 11348
11352 11349
11353 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, 11350 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code,
11354 const char* reason) { 11351 const char* reason) {
11355 DisallowHeapAllocation no_gc; 11352 DisallowHeapAllocation no_gc;
11356 if (optimized_code_map()->IsSmi()) return; 11353 if (OptimizedCodeMapIsCleared()) return;
11357 11354
11358 Heap* heap = GetHeap(); 11355 Heap* heap = GetHeap();
11359 FixedArray* code_map = FixedArray::cast(optimized_code_map()); 11356 FixedArray* code_map = optimized_code_map();
11360 int dst = kEntriesStart; 11357 int dst = kEntriesStart;
11361 int length = code_map->length(); 11358 int length = code_map->length();
11362 for (int src = kEntriesStart; src < length; src += kEntryLength) { 11359 for (int src = kEntriesStart; src < length; src += kEntryLength) {
11363 DCHECK(code_map->get(src)->IsNativeContext()); 11360 DCHECK(code_map->get(src)->IsNativeContext());
11364 if (code_map->get(src + kCachedCodeOffset) == optimized_code) { 11361 if (code_map->get(src + kCachedCodeOffset) == optimized_code) {
11365 BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value()); 11362 BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value());
11366 if (FLAG_trace_opt) { 11363 if (FLAG_trace_opt) {
11367 PrintF("[evicting entry from optimizing code map (%s) for ", reason); 11364 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
11368 ShortPrint(); 11365 ShortPrint();
11369 if (osr.IsNone()) { 11366 if (osr.IsNone()) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
11408 length - dst); 11405 length - dst);
11409 if (code_map->length() == kEntriesStart && 11406 if (code_map->length() == kEntriesStart &&
11410 code_map->get(kSharedCodeIndex)->IsUndefined()) { 11407 code_map->get(kSharedCodeIndex)->IsUndefined()) {
11411 ClearOptimizedCodeMap(); 11408 ClearOptimizedCodeMap();
11412 } 11409 }
11413 } 11410 }
11414 } 11411 }
11415 11412
11416 11413
11417 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) { 11414 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) {
11418 FixedArray* code_map = FixedArray::cast(optimized_code_map()); 11415 FixedArray* code_map = optimized_code_map();
11419 DCHECK(shrink_by % kEntryLength == 0); 11416 DCHECK(shrink_by % kEntryLength == 0);
11420 DCHECK(shrink_by <= code_map->length() - kEntriesStart); 11417 DCHECK(shrink_by <= code_map->length() - kEntriesStart);
11421 // Always trim even when array is cleared because of heap verifier. 11418 // Always trim even when array is cleared because of heap verifier.
11422 GetHeap()->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(code_map, 11419 GetHeap()->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(code_map,
11423 shrink_by); 11420 shrink_by);
11424 if (code_map->length() == kEntriesStart && 11421 if (code_map->length() == kEntriesStart &&
11425 code_map->get(kSharedCodeIndex)->IsUndefined()) { 11422 code_map->get(kSharedCodeIndex)->IsUndefined()) {
11426 ClearOptimizedCodeMap(); 11423 ClearOptimizedCodeMap();
11427 } 11424 }
11428 } 11425 }
(...skipping 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after
12550 set_opt_count(0); 12547 set_opt_count(0);
12551 set_deopt_count(0); 12548 set_deopt_count(0);
12552 } 12549 }
12553 } 12550 }
12554 12551
12555 12552
12556 int SharedFunctionInfo::SearchOptimizedCodeMapEntry(Context* native_context, 12553 int SharedFunctionInfo::SearchOptimizedCodeMapEntry(Context* native_context,
12557 BailoutId osr_ast_id) { 12554 BailoutId osr_ast_id) {
12558 DisallowHeapAllocation no_gc; 12555 DisallowHeapAllocation no_gc;
12559 DCHECK(native_context->IsNativeContext()); 12556 DCHECK(native_context->IsNativeContext());
12560 Object* value = optimized_code_map(); 12557 if (!OptimizedCodeMapIsCleared()) {
12561 if (!value->IsSmi()) { 12558 FixedArray* optimized_code_map = this->optimized_code_map();
12562 FixedArray* optimized_code_map = FixedArray::cast(value);
12563 int length = optimized_code_map->length(); 12559 int length = optimized_code_map->length();
12564 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); 12560 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt());
12565 for (int i = kEntriesStart; i < length; i += kEntryLength) { 12561 for (int i = kEntriesStart; i < length; i += kEntryLength) {
12566 if (optimized_code_map->get(i + kContextOffset) == native_context && 12562 if (optimized_code_map->get(i + kContextOffset) == native_context &&
12567 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { 12563 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) {
12568 return i; 12564 return i;
12569 } 12565 }
12570 } 12566 }
12571 Object* shared_code = optimized_code_map->get(kSharedCodeIndex); 12567 Object* shared_code = optimized_code_map->get(kSharedCodeIndex);
12572 if (shared_code->IsCode() && osr_ast_id.IsNone()) { 12568 if (shared_code->IsCode() && osr_ast_id.IsNone()) {
12573 return kSharedCodeIndex; 12569 return kSharedCodeIndex;
12574 } 12570 }
12575 } 12571 }
12576 return -1; 12572 return -1;
12577 } 12573 }
12578 12574
12579 12575
12580 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( 12576 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap(
12581 Context* native_context, BailoutId osr_ast_id) { 12577 Context* native_context, BailoutId osr_ast_id) {
12582 CodeAndLiterals result = {nullptr, nullptr}; 12578 CodeAndLiterals result = {nullptr, nullptr};
12583 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id); 12579 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id);
12584 if (entry != kNotFound) { 12580 if (entry != kNotFound) {
12585 FixedArray* code_map = FixedArray::cast(optimized_code_map()); 12581 FixedArray* code_map = optimized_code_map();
12586 if (entry == kSharedCodeIndex) { 12582 if (entry == kSharedCodeIndex) {
12587 result = {Code::cast(code_map->get(kSharedCodeIndex)), nullptr}; 12583 result = {Code::cast(code_map->get(kSharedCodeIndex)), nullptr};
12588 12584
12589 } else { 12585 } else {
12590 DCHECK_LE(entry + kEntryLength, code_map->length()); 12586 DCHECK_LE(entry + kEntryLength, code_map->length());
12591 Object* code = code_map->get(entry + kCachedCodeOffset); 12587 Object* code = code_map->get(entry + kCachedCodeOffset);
12592 result = {code->IsUndefined() ? nullptr : Code::cast(code), 12588 result = {code->IsUndefined() ? nullptr : Code::cast(code),
12593 LiteralsArray::cast(code_map->get(entry + kLiteralsOffset))}; 12589 LiteralsArray::cast(code_map->get(entry + kLiteralsOffset))};
12594 } 12590 }
12595 } 12591 }
12596 if (FLAG_trace_opt && !optimized_code_map()->IsSmi() && 12592 if (FLAG_trace_opt && !OptimizedCodeMapIsCleared() &&
12597 result.code == nullptr) { 12593 result.code == nullptr) {
12598 PrintF("[didn't find optimized code in optimized code map for "); 12594 PrintF("[didn't find optimized code in optimized code map for ");
12599 ShortPrint(); 12595 ShortPrint();
12600 PrintF("]\n"); 12596 PrintF("]\n");
12601 } 12597 }
12602 return result; 12598 return result;
12603 } 12599 }
12604 12600
12605 12601
12606 #define DECLARE_TAG(ignore1, name, ignore2) name, 12602 #define DECLARE_TAG(ignore1, name, ignore2) name,
(...skipping 5516 matching lines...) Expand 10 before | Expand all | Expand 10 after
18123 if (cell->value() != *new_value) { 18119 if (cell->value() != *new_value) {
18124 cell->set_value(*new_value); 18120 cell->set_value(*new_value);
18125 Isolate* isolate = cell->GetIsolate(); 18121 Isolate* isolate = cell->GetIsolate();
18126 cell->dependent_code()->DeoptimizeDependentCodeGroup( 18122 cell->dependent_code()->DeoptimizeDependentCodeGroup(
18127 isolate, DependentCode::kPropertyCellChangedGroup); 18123 isolate, DependentCode::kPropertyCellChangedGroup);
18128 } 18124 }
18129 } 18125 }
18130 18126
18131 } // namespace internal 18127 } // namespace internal
18132 } // namespace v8 18128 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698