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

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: More fixes Created 5 years, 3 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
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 10125 matching lines...) Expand 10 before | Expand all | Expand 10 after
10136 } 10136 }
10137 10137
10138 10138
10139 void SharedFunctionInfo::AddToOptimizedCodeMap( 10139 void SharedFunctionInfo::AddToOptimizedCodeMap(
10140 Handle<SharedFunctionInfo> shared, 10140 Handle<SharedFunctionInfo> shared,
10141 Handle<Context> native_context, 10141 Handle<Context> native_context,
10142 Handle<Code> code, 10142 Handle<Code> code,
10143 Handle<FixedArray> literals, 10143 Handle<FixedArray> literals,
10144 BailoutId osr_ast_id) { 10144 BailoutId osr_ast_id) {
10145 Isolate* isolate = shared->GetIsolate(); 10145 Isolate* isolate = shared->GetIsolate();
10146 DCHECK(!shared->SearchOptimizedCodeMap(*native_context, osr_ast_id).code); 10146 DCHECK(code.is_null() ||
10147 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); 10147 !shared->SearchOptimizedCodeMap(*native_context, osr_ast_id).code);
10148 DCHECK(code.is_null() || code->kind() == Code::OPTIMIZED_FUNCTION);
10148 DCHECK(native_context->IsNativeContext()); 10149 DCHECK(native_context->IsNativeContext());
10149 STATIC_ASSERT(kEntryLength == 4); 10150 STATIC_ASSERT(kEntryLength == 4);
10150 Handle<FixedArray> new_code_map; 10151 Handle<FixedArray> new_code_map;
10151 Handle<Object> value(shared->optimized_code_map(), isolate); 10152 Handle<Object> value(shared->optimized_code_map(), isolate);
10152 int old_length; 10153 int old_length;
10153 if (value->IsSmi()) { 10154 if (value->IsSmi()) {
10154 // No optimized code map. 10155 // No optimized code map.
10155 DCHECK_EQ(0, Smi::cast(*value)->value()); 10156 DCHECK_EQ(0, Smi::cast(*value)->value());
10156 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); 10157 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED);
10157 old_length = kEntriesStart; 10158 old_length = kEntriesStart;
10158 } else { 10159 } else {
10160 Handle<FixedArray> old_code_map = Handle<FixedArray>::cast(value);
10161 int entry =
10162 shared->SearchOptimizedCodeMapEntry(*native_context, osr_ast_id);
10163 if (entry > kSharedCodeIndex) {
10164 // Found an existing context-specific entry, it must not contain any code.
10165 DCHECK(old_code_map->get(entry + kCachedCodeOffset) == nullptr);
10166 // Just set the code and literals to the entry.
10167 if (!code.is_null()) {
10168 old_code_map->set(entry + kCachedCodeOffset, *code);
10169 }
10170 old_code_map->set(entry + kLiteralsOffset, *literals);
10171 return;
10172 }
10173
10159 // Copy old optimized code map and append one new entry. 10174 // 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( 10175 new_code_map = isolate->factory()->CopyFixedArrayAndGrow(
10162 old_code_map, kEntryLength, TENURED); 10176 old_code_map, kEntryLength, TENURED);
10163 old_length = old_code_map->length(); 10177 old_length = old_code_map->length();
10164 // Zap the old map to avoid any stale entries. Note that this is required 10178 // 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. 10179 // for correctness because entries are being treated weakly by the GC.
10166 MemsetPointer(old_code_map->data_start(), isolate->heap()->the_hole_value(), 10180 MemsetPointer(old_code_map->data_start(), isolate->heap()->the_hole_value(),
10167 old_length); 10181 old_length);
10168 } 10182 }
10169 new_code_map->set(old_length + kContextOffset, *native_context); 10183 new_code_map->set(old_length + kContextOffset, *native_context);
10170 new_code_map->set(old_length + kCachedCodeOffset, *code); 10184 new_code_map->set(old_length + kCachedCodeOffset,
10185 code.is_null() ? nullptr : *code);
10171 new_code_map->set(old_length + kLiteralsOffset, *literals); 10186 new_code_map->set(old_length + kLiteralsOffset, *literals);
10172 new_code_map->set(old_length + kOsrAstIdOffset, 10187 new_code_map->set(old_length + kOsrAstIdOffset,
10173 Smi::FromInt(osr_ast_id.ToInt())); 10188 Smi::FromInt(osr_ast_id.ToInt()));
10174 10189
10175 #ifdef DEBUG 10190 #ifdef DEBUG
10176 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { 10191 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
10177 DCHECK(new_code_map->get(i + kContextOffset)->IsNativeContext()); 10192 DCHECK(new_code_map->get(i + kContextOffset)->IsNativeContext());
10178 DCHECK(new_code_map->get(i + kCachedCodeOffset)->IsCode()); 10193 Object* code = new_code_map->get(i + kCachedCodeOffset);
10179 DCHECK(Code::cast(new_code_map->get(i + kCachedCodeOffset))->kind() == 10194 if (code != nullptr) {
10180 Code::OPTIMIZED_FUNCTION); 10195 DCHECK(code->IsCode());
10196 DCHECK(Code::cast(code)->kind() == Code::OPTIMIZED_FUNCTION);
10197 }
10181 DCHECK(new_code_map->get(i + kLiteralsOffset)->IsFixedArray()); 10198 DCHECK(new_code_map->get(i + kLiteralsOffset)->IsFixedArray());
10182 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); 10199 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi());
10183 } 10200 }
10184 #endif 10201 #endif
10185 shared->set_optimized_code_map(*new_code_map); 10202 shared->set_optimized_code_map(*new_code_map);
10186 } 10203 }
10187 10204
10188 10205
10189 void SharedFunctionInfo::ClearOptimizedCodeMap() { 10206 void SharedFunctionInfo::ClearOptimizedCodeMap() {
10190 FixedArray* code_map = FixedArray::cast(optimized_code_map()); 10207 FixedArray* code_map = FixedArray::cast(optimized_code_map());
(...skipping 13 matching lines...) Expand all
10204 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, 10221 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code,
10205 const char* reason) { 10222 const char* reason) {
10206 DisallowHeapAllocation no_gc; 10223 DisallowHeapAllocation no_gc;
10207 if (optimized_code_map()->IsSmi()) return; 10224 if (optimized_code_map()->IsSmi()) return;
10208 10225
10209 FixedArray* code_map = FixedArray::cast(optimized_code_map()); 10226 FixedArray* code_map = FixedArray::cast(optimized_code_map());
10210 int dst = kEntriesStart; 10227 int dst = kEntriesStart;
10211 int length = code_map->length(); 10228 int length = code_map->length();
10212 for (int src = kEntriesStart; src < length; src += kEntryLength) { 10229 for (int src = kEntriesStart; src < length; src += kEntryLength) {
10213 DCHECK(code_map->get(src)->IsNativeContext()); 10230 DCHECK(code_map->get(src)->IsNativeContext());
10214 if (Code::cast(code_map->get(src + kCachedCodeOffset)) == optimized_code) { 10231 if (code_map->get(src + kCachedCodeOffset) == optimized_code) {
10215 // Evict the src entry by not copying it to the dst entry. 10232 BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value());
10216 if (FLAG_trace_opt) { 10233 if (FLAG_trace_opt) {
10217 PrintF("[evicting entry from optimizing code map (%s) for ", reason); 10234 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
10218 ShortPrint(); 10235 ShortPrint();
10219 BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value());
10220 if (osr.IsNone()) { 10236 if (osr.IsNone()) {
10221 PrintF("]\n"); 10237 PrintF("]\n");
10222 } else { 10238 } else {
10223 PrintF(" (osr ast id %d)]\n", osr.ToInt()); 10239 PrintF(" (osr ast id %d)]\n", osr.ToInt());
10224 } 10240 }
10225 } 10241 }
10226 } else { 10242 if (!osr.IsNone()) {
10227 // Keep the src entry by copying it to the dst entry. 10243 // Evict the src entry by not copying it to the dst entry.
10228 if (dst != src) { 10244 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 } 10245 }
10238 dst += kEntryLength; 10246 // In case of non-OSR entry just clear the code in order to proceed
10247 // sharing literals.
10248 code_map->set(src + kCachedCodeOffset, static_cast<Code*>(nullptr));
10239 } 10249 }
10250
10251 // Keep the src entry by copying it to the dst entry.
10252 if (dst != src) {
10253 code_map->set(dst + kContextOffset, code_map->get(src + kContextOffset));
10254 code_map->set(dst + kCachedCodeOffset,
10255 code_map->get(src + kCachedCodeOffset));
10256 code_map->set(dst + kLiteralsOffset,
10257 code_map->get(src + kLiteralsOffset));
10258 code_map->set(dst + kOsrAstIdOffset,
10259 code_map->get(src + kOsrAstIdOffset));
10260 }
10261 dst += kEntryLength;
10240 } 10262 }
10241 if (code_map->get(kSharedCodeIndex) == optimized_code) { 10263 if (code_map->get(kSharedCodeIndex) == optimized_code) {
10242 // Evict context-independent code as well. 10264 // Evict context-independent code as well.
10243 code_map->set_undefined(kSharedCodeIndex); 10265 code_map->set_undefined(kSharedCodeIndex);
10244 if (FLAG_trace_opt) { 10266 if (FLAG_trace_opt) {
10245 PrintF("[evicting entry from optimizing code map (%s) for ", reason); 10267 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
10246 ShortPrint(); 10268 ShortPrint();
10247 PrintF(" (context-independent code)]\n"); 10269 PrintF(" (context-independent code)]\n");
10248 } 10270 }
10249 } 10271 }
(...skipping 1008 matching lines...) Expand 10 before | Expand all | Expand 10 after
11258 opt_count() >= FLAG_max_opt_count) { 11280 opt_count() >= FLAG_max_opt_count) {
11259 // Re-enable optimizations if they were disabled due to opt_count limit. 11281 // Re-enable optimizations if they were disabled due to opt_count limit.
11260 set_optimization_disabled(false); 11282 set_optimization_disabled(false);
11261 } 11283 }
11262 set_opt_count(0); 11284 set_opt_count(0);
11263 set_deopt_count(0); 11285 set_deopt_count(0);
11264 } 11286 }
11265 } 11287 }
11266 11288
11267 11289
11268 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( 11290 int SharedFunctionInfo::SearchOptimizedCodeMapEntry(Context* native_context,
11269 Context* native_context, BailoutId osr_ast_id) { 11291 BailoutId osr_ast_id) {
11270 DisallowHeapAllocation no_gc; 11292 DisallowHeapAllocation no_gc;
11271 DCHECK(native_context->IsNativeContext()); 11293 DCHECK(native_context->IsNativeContext());
11272 Object* value = optimized_code_map(); 11294 Object* value = optimized_code_map();
11273 if (!value->IsSmi()) { 11295 if (!value->IsSmi()) {
11274 FixedArray* optimized_code_map = FixedArray::cast(value); 11296 FixedArray* optimized_code_map = FixedArray::cast(value);
11275 int length = optimized_code_map->length(); 11297 int length = optimized_code_map->length();
11276 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); 11298 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt());
11277 for (int i = kEntriesStart; i < length; i += kEntryLength) { 11299 for (int i = kEntriesStart; i < length; i += kEntryLength) {
11278 if (optimized_code_map->get(i + kContextOffset) == native_context && 11300 if (optimized_code_map->get(i + kContextOffset) == native_context &&
11279 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { 11301 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) {
11280 return {Code::cast(optimized_code_map->get(i + kCachedCodeOffset)), 11302 return i;
11281 FixedArray::cast(optimized_code_map->get(i + kLiteralsOffset))};
11282 } 11303 }
11283 } 11304 }
11284 Object* shared_code = optimized_code_map->get(kSharedCodeIndex); 11305 Object* shared_code = optimized_code_map->get(kSharedCodeIndex);
11285 if (shared_code->IsCode() && osr_ast_id.IsNone()) { 11306 if (shared_code->IsCode() && osr_ast_id.IsNone()) {
11286 return {Code::cast(shared_code), nullptr}; 11307 return kSharedCodeIndex;
11287 } 11308 }
11288 if (FLAG_trace_opt) { 11309 if (FLAG_trace_opt) {
Michael Starzinger 2015/09/22 10:57:34 This tracing will also be printed when adding new
Igor Sheludko 2015/09/22 12:58:11 Fixed.
11289 PrintF("[didn't find optimized code in optimized code map for "); 11310 PrintF("[didn't find optimized code in optimized code map for ");
11290 ShortPrint(); 11311 ShortPrint();
11291 PrintF("]\n"); 11312 PrintF("]\n");
11292 } 11313 }
11293 } 11314 }
11294 return {nullptr, nullptr}; 11315 return -1;
11295 } 11316 }
11296 11317
11297 11318
11319 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap(
11320 Context* native_context, BailoutId osr_ast_id) {
11321 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id);
11322 if (entry == kNotFound) return {nullptr, nullptr};
11323
11324 FixedArray* code_map = FixedArray::cast(optimized_code_map());
11325 if (entry == kSharedCodeIndex) {
11326 return {Code::cast(code_map->get(kSharedCodeIndex)), nullptr};
11327 }
11328 DCHECK_LE(entry + kEntryLength, code_map->length());
11329 Object* code = code_map->get(entry + kCachedCodeOffset);
11330 return {code == nullptr ? nullptr : Code::cast(code),
11331 FixedArray::cast(code_map->get(entry + kLiteralsOffset))};
11332 }
11333
11334
11298 #define DECLARE_TAG(ignore1, name, ignore2) name, 11335 #define DECLARE_TAG(ignore1, name, ignore2) name,
11299 const char* const VisitorSynchronization::kTags[ 11336 const char* const VisitorSynchronization::kTags[
11300 VisitorSynchronization::kNumberOfSyncTags] = { 11337 VisitorSynchronization::kNumberOfSyncTags] = {
11301 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) 11338 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG)
11302 }; 11339 };
11303 #undef DECLARE_TAG 11340 #undef DECLARE_TAG
11304 11341
11305 11342
11306 #define DECLARE_TAG(ignore1, ignore2, name) name, 11343 #define DECLARE_TAG(ignore1, ignore2, name) name,
11307 const char* const VisitorSynchronization::kTagNames[ 11344 const char* const VisitorSynchronization::kTagNames[
(...skipping 5382 matching lines...) Expand 10 before | Expand all | Expand 10 after
16690 if (cell->value() != *new_value) { 16727 if (cell->value() != *new_value) {
16691 cell->set_value(*new_value); 16728 cell->set_value(*new_value);
16692 Isolate* isolate = cell->GetIsolate(); 16729 Isolate* isolate = cell->GetIsolate();
16693 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16730 cell->dependent_code()->DeoptimizeDependentCodeGroup(
16694 isolate, DependentCode::kPropertyCellChangedGroup); 16731 isolate, DependentCode::kPropertyCellChangedGroup);
16695 } 16732 }
16696 } 16733 }
16697 16734
16698 } // namespace internal 16735 } // namespace internal
16699 } // namespace v8 16736 } // namespace v8
OLDNEW
« src/objects.h ('K') | « 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