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

Side by Side Diff: src/objects.cc

Issue 1353363002: Share literals arrays per <NativeContext, SharedFunctionInfo> pair. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressing comments Created 5 years, 2 months 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') | test/mjsunit/array-natives-elements.js » ('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 10119 matching lines...) Expand 10 before | Expand all | Expand 10 after
10130 Isolate* isolate = shared->GetIsolate(); 10130 Isolate* isolate = shared->GetIsolate();
10131 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); 10131 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
10132 Handle<Object> value(shared->optimized_code_map(), isolate); 10132 Handle<Object> value(shared->optimized_code_map(), isolate);
10133 if (value->IsSmi()) return; // Empty code maps are unsupported. 10133 if (value->IsSmi()) return; // Empty code maps are unsupported.
10134 Handle<FixedArray> code_map = Handle<FixedArray>::cast(value); 10134 Handle<FixedArray> code_map = Handle<FixedArray>::cast(value);
10135 code_map->set(kSharedCodeIndex, *code); 10135 code_map->set(kSharedCodeIndex, *code);
10136 } 10136 }
10137 10137
10138 10138
10139 void SharedFunctionInfo::AddToOptimizedCodeMap( 10139 void SharedFunctionInfo::AddToOptimizedCodeMap(
10140 Handle<SharedFunctionInfo> shared, 10140 Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
10141 Handle<Context> native_context, 10141 Handle<HeapObject> code, Handle<FixedArray> literals,
10142 Handle<Code> code,
10143 Handle<FixedArray> literals,
10144 BailoutId osr_ast_id) { 10142 BailoutId osr_ast_id) {
10145 Isolate* isolate = shared->GetIsolate(); 10143 Isolate* isolate = shared->GetIsolate();
10146 DCHECK(!shared->SearchOptimizedCodeMap(*native_context, osr_ast_id).code); 10144 DCHECK(*code == isolate->heap()->undefined_value() ||
10147 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); 10145 !shared->SearchOptimizedCodeMap(*native_context, osr_ast_id).code);
10146 DCHECK(*code == isolate->heap()->undefined_value() ||
10147 Code::cast(*code)->kind() == Code::OPTIMIZED_FUNCTION);
10148 DCHECK(native_context->IsNativeContext()); 10148 DCHECK(native_context->IsNativeContext());
10149 STATIC_ASSERT(kEntryLength == 4); 10149 STATIC_ASSERT(kEntryLength == 4);
10150 Handle<FixedArray> new_code_map; 10150 Handle<FixedArray> new_code_map;
10151 Handle<Object> value(shared->optimized_code_map(), isolate); 10151 Handle<Object> value(shared->optimized_code_map(), isolate);
10152 int old_length; 10152 int entry;
10153 if (value->IsSmi()) { 10153 if (value->IsSmi()) {
10154 // No optimized code map. 10154 // No optimized code map.
10155 DCHECK_EQ(0, Smi::cast(*value)->value()); 10155 DCHECK_EQ(0, Smi::cast(*value)->value());
10156 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); 10156 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED);
10157 old_length = kEntriesStart; 10157 entry = kEntriesStart;
10158 } else { 10158 } else {
10159 Handle<FixedArray> old_code_map = Handle<FixedArray>::cast(value);
10160 entry = shared->SearchOptimizedCodeMapEntry(*native_context, osr_ast_id);
10161 if (entry > kSharedCodeIndex) {
10162 // Found an existing context-specific entry, it must not contain any code.
10163 DCHECK_EQ(isolate->heap()->undefined_value(),
10164 old_code_map->get(entry + kCachedCodeOffset));
10165 // Just set the code and literals to the entry.
10166 old_code_map->set(entry + kCachedCodeOffset, *code);
10167 old_code_map->set(entry + kLiteralsOffset, *literals);
10168 return;
10169 }
10170
10159 // Copy old optimized code map and append one new entry. 10171 // Copy old optimized code map and append one new entry.
10160 Handle<FixedArray> old_code_map = Handle<FixedArray>::cast(value);
10161 new_code_map = isolate->factory()->CopyFixedArrayAndGrow( 10172 new_code_map = isolate->factory()->CopyFixedArrayAndGrow(
10162 old_code_map, kEntryLength, TENURED); 10173 old_code_map, kEntryLength, TENURED);
10163 old_length = old_code_map->length(); 10174 int old_length = old_code_map->length();
10164 // Zap the old map to avoid any stale entries. Note that this is required 10175 // Zap the old map to avoid any stale entries. Note that this is required
10165 // for correctness because entries are being treated weakly by the GC. 10176 // for correctness because entries are being treated weakly by the GC.
10166 MemsetPointer(old_code_map->data_start(), isolate->heap()->the_hole_value(), 10177 MemsetPointer(old_code_map->data_start(), isolate->heap()->the_hole_value(),
10167 old_length); 10178 old_length);
10179 entry = old_length;
10168 } 10180 }
10169 new_code_map->set(old_length + kContextOffset, *native_context); 10181 new_code_map->set(entry + kContextOffset, *native_context);
10170 new_code_map->set(old_length + kCachedCodeOffset, *code); 10182 new_code_map->set(entry + kCachedCodeOffset, *code);
10171 new_code_map->set(old_length + kLiteralsOffset, *literals); 10183 new_code_map->set(entry + kLiteralsOffset, *literals);
10172 new_code_map->set(old_length + kOsrAstIdOffset, 10184 new_code_map->set(entry + kOsrAstIdOffset, Smi::FromInt(osr_ast_id.ToInt()));
10173 Smi::FromInt(osr_ast_id.ToInt()));
10174 10185
10175 #ifdef DEBUG 10186 #ifdef DEBUG
10176 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { 10187 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
10177 DCHECK(new_code_map->get(i + kContextOffset)->IsNativeContext()); 10188 DCHECK(new_code_map->get(i + kContextOffset)->IsNativeContext());
10178 DCHECK(new_code_map->get(i + kCachedCodeOffset)->IsCode()); 10189 Object* code = new_code_map->get(i + kCachedCodeOffset);
10179 DCHECK(Code::cast(new_code_map->get(i + kCachedCodeOffset))->kind() == 10190 if (code != isolate->heap()->undefined_value()) {
10180 Code::OPTIMIZED_FUNCTION); 10191 DCHECK(code->IsCode());
10192 DCHECK(Code::cast(code)->kind() == Code::OPTIMIZED_FUNCTION);
10193 }
10181 DCHECK(new_code_map->get(i + kLiteralsOffset)->IsFixedArray()); 10194 DCHECK(new_code_map->get(i + kLiteralsOffset)->IsFixedArray());
10182 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); 10195 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi());
10183 } 10196 }
10184 #endif 10197 #endif
10185 shared->set_optimized_code_map(*new_code_map); 10198 shared->set_optimized_code_map(*new_code_map);
10186 } 10199 }
10187 10200
10188 10201
10189 void SharedFunctionInfo::ClearOptimizedCodeMap() { 10202 void SharedFunctionInfo::ClearOptimizedCodeMap() {
10190 FixedArray* code_map = FixedArray::cast(optimized_code_map()); 10203 FixedArray* code_map = FixedArray::cast(optimized_code_map());
10191 10204
10192 // If the next map link slot is already used then the function was 10205 // If the next map link slot is already used then the function was
10193 // enqueued with code flushing and we remove it now. 10206 // enqueued with code flushing and we remove it now.
10194 if (!code_map->get(kNextMapIndex)->IsUndefined()) { 10207 if (!code_map->get(kNextMapIndex)->IsUndefined()) {
10195 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher(); 10208 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher();
10196 flusher->EvictOptimizedCodeMap(this); 10209 flusher->EvictOptimizedCodeMap(this);
10197 } 10210 }
10198 10211
10199 DCHECK(code_map->get(kNextMapIndex)->IsUndefined()); 10212 DCHECK(code_map->get(kNextMapIndex)->IsUndefined());
10200 set_optimized_code_map(Smi::FromInt(0)); 10213 set_optimized_code_map(Smi::FromInt(0));
10201 } 10214 }
10202 10215
10203 10216
10204 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, 10217 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code,
10205 const char* reason) { 10218 const char* reason) {
10206 DisallowHeapAllocation no_gc; 10219 DisallowHeapAllocation no_gc;
10207 if (optimized_code_map()->IsSmi()) return; 10220 if (optimized_code_map()->IsSmi()) return;
10208 10221
10222 Heap* heap = GetHeap();
10209 FixedArray* code_map = FixedArray::cast(optimized_code_map()); 10223 FixedArray* code_map = FixedArray::cast(optimized_code_map());
10210 int dst = kEntriesStart; 10224 int dst = kEntriesStart;
10211 int length = code_map->length(); 10225 int length = code_map->length();
10212 for (int src = kEntriesStart; src < length; src += kEntryLength) { 10226 for (int src = kEntriesStart; src < length; src += kEntryLength) {
10213 DCHECK(code_map->get(src)->IsNativeContext()); 10227 DCHECK(code_map->get(src)->IsNativeContext());
10214 if (Code::cast(code_map->get(src + kCachedCodeOffset)) == optimized_code) { 10228 if (code_map->get(src + kCachedCodeOffset) == optimized_code) {
10215 // Evict the src entry by not copying it to the dst entry. 10229 BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value());
10216 if (FLAG_trace_opt) { 10230 if (FLAG_trace_opt) {
10217 PrintF("[evicting entry from optimizing code map (%s) for ", reason); 10231 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
10218 ShortPrint(); 10232 ShortPrint();
10219 BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value());
10220 if (osr.IsNone()) { 10233 if (osr.IsNone()) {
10221 PrintF("]\n"); 10234 PrintF("]\n");
10222 } else { 10235 } else {
10223 PrintF(" (osr ast id %d)]\n", osr.ToInt()); 10236 PrintF(" (osr ast id %d)]\n", osr.ToInt());
10224 } 10237 }
10225 } 10238 }
10226 } else { 10239 if (!osr.IsNone()) {
10227 // Keep the src entry by copying it to the dst entry. 10240 // Evict the src entry by not copying it to the dst entry.
10228 if (dst != src) { 10241 continue;
10229 code_map->set(dst + kContextOffset,
10230 code_map->get(src + kContextOffset));
10231 code_map->set(dst + kCachedCodeOffset,
10232 code_map->get(src + kCachedCodeOffset));
10233 code_map->set(dst + kLiteralsOffset,
10234 code_map->get(src + kLiteralsOffset));
10235 code_map->set(dst + kOsrAstIdOffset,
10236 code_map->get(src + kOsrAstIdOffset));
10237 } 10242 }
10238 dst += kEntryLength; 10243 // In case of non-OSR entry just clear the code in order to proceed
10244 // sharing literals.
10245 code_map->set_undefined(src + kCachedCodeOffset);
10239 } 10246 }
10247
10248 // Keep the src entry by copying it to the dst entry.
10249 if (dst != src) {
10250 code_map->set(dst + kContextOffset, code_map->get(src + kContextOffset));
10251 code_map->set(dst + kCachedCodeOffset,
10252 code_map->get(src + kCachedCodeOffset));
10253 code_map->set(dst + kLiteralsOffset,
10254 code_map->get(src + kLiteralsOffset));
10255 code_map->set(dst + kOsrAstIdOffset,
10256 code_map->get(src + kOsrAstIdOffset));
10257 }
10258 dst += kEntryLength;
10240 } 10259 }
10241 if (code_map->get(kSharedCodeIndex) == optimized_code) { 10260 if (code_map->get(kSharedCodeIndex) == optimized_code) {
10242 // Evict context-independent code as well. 10261 // Evict context-independent code as well.
10243 code_map->set_undefined(kSharedCodeIndex); 10262 code_map->set_undefined(kSharedCodeIndex);
10244 if (FLAG_trace_opt) { 10263 if (FLAG_trace_opt) {
10245 PrintF("[evicting entry from optimizing code map (%s) for ", reason); 10264 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
10246 ShortPrint(); 10265 ShortPrint();
10247 PrintF(" (context-independent code)]\n"); 10266 PrintF(" (context-independent code)]\n");
10248 } 10267 }
10249 } 10268 }
10250 if (dst != length) { 10269 if (dst != length) {
10251 // Always trim even when array is cleared because of heap verifier. 10270 // Always trim even when array is cleared because of heap verifier.
10252 GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(code_map, 10271 heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(code_map,
10253 length - dst); 10272 length - dst);
10254 if (code_map->length() == kEntriesStart && 10273 if (code_map->length() == kEntriesStart &&
10255 code_map->get(kSharedCodeIndex)->IsUndefined()) { 10274 code_map->get(kSharedCodeIndex)->IsUndefined()) {
10256 ClearOptimizedCodeMap(); 10275 ClearOptimizedCodeMap();
10257 } 10276 }
10258 } 10277 }
10259 } 10278 }
10260 10279
10261 10280
10262 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) { 10281 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) {
10263 FixedArray* code_map = FixedArray::cast(optimized_code_map()); 10282 FixedArray* code_map = FixedArray::cast(optimized_code_map());
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after
11258 opt_count() >= FLAG_max_opt_count) { 11277 opt_count() >= FLAG_max_opt_count) {
11259 // Re-enable optimizations if they were disabled due to opt_count limit. 11278 // Re-enable optimizations if they were disabled due to opt_count limit.
11260 set_optimization_disabled(false); 11279 set_optimization_disabled(false);
11261 } 11280 }
11262 set_opt_count(0); 11281 set_opt_count(0);
11263 set_deopt_count(0); 11282 set_deopt_count(0);
11264 } 11283 }
11265 } 11284 }
11266 11285
11267 11286
11268 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( 11287 int SharedFunctionInfo::SearchOptimizedCodeMapEntry(Context* native_context,
11269 Context* native_context, BailoutId osr_ast_id) { 11288 BailoutId osr_ast_id) {
11270 DisallowHeapAllocation no_gc; 11289 DisallowHeapAllocation no_gc;
11271 DCHECK(native_context->IsNativeContext()); 11290 DCHECK(native_context->IsNativeContext());
11272 Object* value = optimized_code_map(); 11291 Object* value = optimized_code_map();
11273 if (!value->IsSmi()) { 11292 if (!value->IsSmi()) {
11274 FixedArray* optimized_code_map = FixedArray::cast(value); 11293 FixedArray* optimized_code_map = FixedArray::cast(value);
11275 int length = optimized_code_map->length(); 11294 int length = optimized_code_map->length();
11276 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); 11295 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt());
11277 for (int i = kEntriesStart; i < length; i += kEntryLength) { 11296 for (int i = kEntriesStart; i < length; i += kEntryLength) {
11278 if (optimized_code_map->get(i + kContextOffset) == native_context && 11297 if (optimized_code_map->get(i + kContextOffset) == native_context &&
11279 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { 11298 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) {
11280 return {Code::cast(optimized_code_map->get(i + kCachedCodeOffset)), 11299 return i;
11281 FixedArray::cast(optimized_code_map->get(i + kLiteralsOffset))};
11282 } 11300 }
11283 } 11301 }
11284 Object* shared_code = optimized_code_map->get(kSharedCodeIndex); 11302 Object* shared_code = optimized_code_map->get(kSharedCodeIndex);
11285 if (shared_code->IsCode() && osr_ast_id.IsNone()) { 11303 if (shared_code->IsCode() && osr_ast_id.IsNone()) {
11286 return {Code::cast(shared_code), nullptr}; 11304 return kSharedCodeIndex;
11287 }
11288 if (FLAG_trace_opt) {
11289 PrintF("[didn't find optimized code in optimized code map for ");
11290 ShortPrint();
11291 PrintF("]\n");
11292 } 11305 }
11293 } 11306 }
11294 return {nullptr, nullptr}; 11307 return -1;
11295 } 11308 }
11296 11309
11297 11310
11311 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap(
11312 Context* native_context, BailoutId osr_ast_id) {
11313 CodeAndLiterals result = {nullptr, nullptr};
11314 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id);
11315 if (entry != kNotFound) {
11316 FixedArray* code_map = FixedArray::cast(optimized_code_map());
11317 if (entry == kSharedCodeIndex) {
11318 result = {Code::cast(code_map->get(kSharedCodeIndex)), nullptr};
11319
11320 } else {
11321 DCHECK_LE(entry + kEntryLength, code_map->length());
11322 Object* code = code_map->get(entry + kCachedCodeOffset);
11323 result = {code->IsUndefined() ? nullptr : Code::cast(code),
11324 FixedArray::cast(code_map->get(entry + kLiteralsOffset))};
11325 }
11326 }
11327 if (FLAG_trace_opt && !optimized_code_map()->IsSmi() &&
11328 result.code == nullptr) {
11329 PrintF("[didn't find optimized code in optimized code map for ");
11330 ShortPrint();
11331 PrintF("]\n");
11332 }
11333 return result;
11334 }
11335
11336
11298 #define DECLARE_TAG(ignore1, name, ignore2) name, 11337 #define DECLARE_TAG(ignore1, name, ignore2) name,
11299 const char* const VisitorSynchronization::kTags[ 11338 const char* const VisitorSynchronization::kTags[
11300 VisitorSynchronization::kNumberOfSyncTags] = { 11339 VisitorSynchronization::kNumberOfSyncTags] = {
11301 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) 11340 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG)
11302 }; 11341 };
11303 #undef DECLARE_TAG 11342 #undef DECLARE_TAG
11304 11343
11305 11344
11306 #define DECLARE_TAG(ignore1, ignore2, name) name, 11345 #define DECLARE_TAG(ignore1, ignore2, name) name,
11307 const char* const VisitorSynchronization::kTagNames[ 11346 const char* const VisitorSynchronization::kTagNames[
(...skipping 5382 matching lines...) Expand 10 before | Expand all | Expand 10 after
16690 if (cell->value() != *new_value) { 16729 if (cell->value() != *new_value) {
16691 cell->set_value(*new_value); 16730 cell->set_value(*new_value);
16692 Isolate* isolate = cell->GetIsolate(); 16731 Isolate* isolate = cell->GetIsolate();
16693 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16732 cell->dependent_code()->DeoptimizeDependentCodeGroup(
16694 isolate, DependentCode::kPropertyCellChangedGroup); 16733 isolate, DependentCode::kPropertyCellChangedGroup);
16695 } 16734 }
16696 } 16735 }
16697 16736
16698 } // namespace internal 16737 } // namespace internal
16699 } // namespace v8 16738 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/array-natives-elements.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698