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

Side by Side Diff: src/objects.cc

Issue 14794007: Preserve optimized code map during GCs weakly. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Ported to other architecture. Created 7 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-visiting-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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2168 matching lines...) Expand 10 before | Expand all | Expand 10 after
2179 // For now this trick is only applied to fixed arrays in new and paged space. 2179 // For now this trick is only applied to fixed arrays in new and paged space.
2180 ASSERT(!HEAP->lo_space()->Contains(elms)); 2180 ASSERT(!HEAP->lo_space()->Contains(elms));
2181 2181
2182 const int len = elms->length(); 2182 const int len = elms->length();
2183 2183
2184 ASSERT(to_trim < len); 2184 ASSERT(to_trim < len);
2185 2185
2186 Address new_end = elms->address() + FixedArray::SizeFor(len - to_trim); 2186 Address new_end = elms->address() + FixedArray::SizeFor(len - to_trim);
2187 2187
2188 if (trim_mode != FROM_GC || Heap::ShouldZapGarbage()) { 2188 if (trim_mode != FROM_GC || Heap::ShouldZapGarbage()) {
2189 ZapEndOfFixedArray(new_end, to_trim); 2189 ZapEndOfFixedArray(new_end, to_trim);
2190 } 2190 }
2191 2191
2192 int size_delta = to_trim * kPointerSize; 2192 int size_delta = to_trim * kPointerSize;
2193 2193
2194 // Technically in new space this write might be omitted (except for 2194 // Technically in new space this write might be omitted (except for
2195 // debug mode which iterates through the heap), but to play safer 2195 // debug mode which iterates through the heap), but to play safer
2196 // we still do it. 2196 // we still do it.
2197 heap->CreateFillerObjectAt(new_end, size_delta); 2197 heap->CreateFillerObjectAt(new_end, size_delta);
2198 2198
2199 elms->set_length(len - to_trim); 2199 elms->set_length(len - to_trim);
(...skipping 6778 matching lines...) Expand 10 before | Expand all | Expand 10 after
8978 Handle<FixedArray> literals) { 8978 Handle<FixedArray> literals) {
8979 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); 8979 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
8980 ASSERT(native_context->IsNativeContext()); 8980 ASSERT(native_context->IsNativeContext());
8981 STATIC_ASSERT(kEntryLength == 3); 8981 STATIC_ASSERT(kEntryLength == 3);
8982 Object* value = shared->optimized_code_map(); 8982 Object* value = shared->optimized_code_map();
8983 Handle<FixedArray> new_code_map; 8983 Handle<FixedArray> new_code_map;
8984 if (value->IsSmi()) { 8984 if (value->IsSmi()) {
8985 // No optimized code map. 8985 // No optimized code map.
8986 ASSERT_EQ(0, Smi::cast(value)->value()); 8986 ASSERT_EQ(0, Smi::cast(value)->value());
8987 // Crate 3 entries per context {context, code, literals}. 8987 // Crate 3 entries per context {context, code, literals}.
8988 new_code_map = FACTORY->NewFixedArray(kEntryLength); 8988 new_code_map = FACTORY->NewFixedArray(kEntriesStart + kEntryLength);
8989 new_code_map->set(0, *native_context); 8989 new_code_map->set(kEntriesStart + 0, *native_context);
8990 new_code_map->set(1, *code); 8990 new_code_map->set(kEntriesStart + 1, *code);
8991 new_code_map->set(2, *literals); 8991 new_code_map->set(kEntriesStart + 2, *literals);
8992 } else { 8992 } else {
8993 // Copy old map and append one new entry. 8993 // Copy old map and append one new entry.
8994 Handle<FixedArray> old_code_map(FixedArray::cast(value)); 8994 Handle<FixedArray> old_code_map(FixedArray::cast(value));
8995 ASSERT_EQ(-1, shared->SearchOptimizedCodeMap(*native_context)); 8995 ASSERT_EQ(-1, shared->SearchOptimizedCodeMap(*native_context));
8996 int old_length = old_code_map->length(); 8996 int old_length = old_code_map->length();
8997 int new_length = old_length + kEntryLength; 8997 int new_length = old_length + kEntryLength;
8998 new_code_map = FACTORY->NewFixedArray(new_length); 8998 new_code_map = FACTORY->NewFixedArray(new_length);
Michael Starzinger 2013/05/14 18:25:05 There is a bug in this part of the code as the cal
Michael Starzinger 2013/05/15 09:44:40 Fixed in patch set 3.
8999 old_code_map->CopyTo(0, *new_code_map, 0, old_length); 8999 old_code_map->CopyTo(0, *new_code_map, 0, old_length);
9000 new_code_map->set(old_length, *native_context); 9000 new_code_map->set(old_length, *native_context);
9001 new_code_map->set(old_length + 1, *code); 9001 new_code_map->set(old_length + 1, *code);
9002 new_code_map->set(old_length + 2, *literals); 9002 new_code_map->set(old_length + 2, *literals);
9003 // Zap the old map for the sake of the heap verifier.
9004 if (Heap::ShouldZapGarbage()) shared->ZapOptimizedCodeMap();
9003 } 9005 }
9004 #ifdef DEBUG 9006 #ifdef DEBUG
9005 for (int i = 0; i < new_code_map->length(); i += kEntryLength) { 9007 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
9006 ASSERT(new_code_map->get(i)->IsNativeContext()); 9008 ASSERT(new_code_map->get(i)->IsNativeContext());
9007 ASSERT(new_code_map->get(i + 1)->IsCode()); 9009 ASSERT(new_code_map->get(i + 1)->IsCode());
9008 ASSERT(Code::cast(new_code_map->get(i + 1))->kind() == 9010 ASSERT(Code::cast(new_code_map->get(i + 1))->kind() ==
9009 Code::OPTIMIZED_FUNCTION); 9011 Code::OPTIMIZED_FUNCTION);
9010 ASSERT(new_code_map->get(i + 2)->IsFixedArray()); 9012 ASSERT(new_code_map->get(i + 2)->IsFixedArray());
9011 } 9013 }
9012 #endif 9014 #endif
9013 shared->set_optimized_code_map(*new_code_map); 9015 shared->set_optimized_code_map(*new_code_map);
9014 } 9016 }
9015 9017
9016 9018
9017 void SharedFunctionInfo::InstallFromOptimizedCodeMap(JSFunction* function, 9019 void SharedFunctionInfo::InstallFromOptimizedCodeMap(JSFunction* function,
9018 int index) { 9020 int index) {
9019 ASSERT(index > 0); 9021 ASSERT(index > kEntriesStart);
9020 ASSERT(optimized_code_map()->IsFixedArray());
9021 FixedArray* code_map = FixedArray::cast(optimized_code_map()); 9022 FixedArray* code_map = FixedArray::cast(optimized_code_map());
9022 if (!bound()) { 9023 if (!bound()) {
9023 FixedArray* cached_literals = FixedArray::cast(code_map->get(index + 1)); 9024 FixedArray* cached_literals = FixedArray::cast(code_map->get(index + 1));
9024 ASSERT(cached_literals != NULL); 9025 ASSERT(cached_literals != NULL);
9025 function->set_literals(cached_literals); 9026 function->set_literals(cached_literals);
9026 } 9027 }
9027 Code* code = Code::cast(code_map->get(index)); 9028 Code* code = Code::cast(code_map->get(index));
9028 ASSERT(code != NULL); 9029 ASSERT(code != NULL);
9029 ASSERT(function->context()->native_context() == code_map->get(index - 1)); 9030 ASSERT(function->context()->native_context() == code_map->get(index - 1));
9030 function->ReplaceCode(code); 9031 function->ReplaceCode(code);
9031 } 9032 }
9032 9033
9033 9034
9034 void SharedFunctionInfo::ClearOptimizedCodeMap(const char* reason) { 9035 void SharedFunctionInfo::ClearOptimizedCodeMap() {
9035 if (!optimized_code_map()->IsSmi()) { 9036 FixedArray* code_map = FixedArray::cast(optimized_code_map());
9036 if (FLAG_trace_opt) { 9037
9037 PrintF("[clearing entire optimizing code map (%s) for ", reason); 9038 // If the next map link slot is already used then the function was
9038 ShortPrint(); 9039 // enqueued with code flushing and we remove it now.
9039 PrintF("]\n"); 9040 if (!code_map->get(kNextMapIndex)->IsUndefined()) {
9040 } 9041 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher();
9041 set_optimized_code_map(Smi::FromInt(0)); 9042 flusher->EvictOptimizedCodeMap(this);
9042 } 9043 }
9044
9045 ASSERT(code_map->get(kNextMapIndex)->IsUndefined());
9046 set_optimized_code_map(Smi::FromInt(0));
9043 } 9047 }
9044 9048
9045 9049
9046 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, 9050 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code,
9047 const char* reason) { 9051 const char* reason) {
9048 if (optimized_code_map()->IsSmi()) return; 9052 if (optimized_code_map()->IsSmi()) return;
9049 9053
9050 int i; 9054 int i;
9051 bool removed_entry = false; 9055 bool removed_entry = false;
9052 FixedArray* code_map = FixedArray::cast(optimized_code_map()); 9056 FixedArray* code_map = FixedArray::cast(optimized_code_map());
9053 for (i = 0; i < code_map->length(); i += kEntryLength) { 9057 for (i = kEntriesStart; i < code_map->length(); i += kEntryLength) {
9054 ASSERT(code_map->get(i)->IsNativeContext()); 9058 ASSERT(code_map->get(i)->IsNativeContext());
9055 if (Code::cast(code_map->get(i + 1)) == optimized_code) { 9059 if (Code::cast(code_map->get(i + 1)) == optimized_code) {
9056 if (FLAG_trace_opt) { 9060 if (FLAG_trace_opt) {
9057 PrintF("[clearing optimizing code map (%s) for ", reason); 9061 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
9058 ShortPrint(); 9062 ShortPrint();
9059 PrintF("]\n"); 9063 PrintF("]\n");
9060 } 9064 }
9061 removed_entry = true; 9065 removed_entry = true;
9062 break; 9066 break;
9063 } 9067 }
9064 } 9068 }
9065 while (i < (code_map->length() - kEntryLength)) { 9069 while (i < (code_map->length() - kEntryLength)) {
9066 code_map->set(i, code_map->get(i + kEntryLength)); 9070 code_map->set(i, code_map->get(i + kEntryLength));
9067 code_map->set(i + 1, code_map->get(i + 1 + kEntryLength)); 9071 code_map->set(i + 1, code_map->get(i + 1 + kEntryLength));
9068 code_map->set(i + 2, code_map->get(i + 2 + kEntryLength)); 9072 code_map->set(i + 2, code_map->get(i + 2 + kEntryLength));
9069 i += kEntryLength; 9073 i += kEntryLength;
9070 } 9074 }
9071 if (removed_entry) { 9075 if (removed_entry) {
9072 if (code_map->length() > kEntryLength) { 9076 // Always trim even when array is cleared because of heap verifier.
9073 RightTrimFixedArray<FROM_MUTATOR>(GetHeap(), code_map, kEntryLength); 9077 RightTrimFixedArray<FROM_MUTATOR>(GetHeap(), code_map, kEntryLength);
9074 } else { 9078 if (code_map->length() == kEntriesStart) {
9075 ClearOptimizedCodeMap(reason); 9079 ClearOptimizedCodeMap();
9076 } 9080 }
9077 } 9081 }
9078 } 9082 }
9079 9083
9080 9084
9085 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) {
9086 FixedArray* code_map = FixedArray::cast(optimized_code_map());
9087 ASSERT(shrink_by % kEntryLength == 0);
9088 ASSERT(shrink_by <= code_map->length() - kEntriesStart);
9089 // Always trim even when array is cleared because of heap verifier.
9090 RightTrimFixedArray<FROM_GC>(GetHeap(), code_map, shrink_by);
9091 if (code_map->length() == kEntriesStart) {
9092 ClearOptimizedCodeMap();
9093 }
9094 }
9095
9096
9097 void SharedFunctionInfo::ZapOptimizedCodeMap() {
9098 FixedArray* code_map = FixedArray::cast(optimized_code_map());
9099 MemsetPointer(code_map->data_start(),
9100 GetHeap()->the_hole_value(),
9101 code_map->length());
9102 }
9103
9104
9081 bool JSFunction::CompileLazy(Handle<JSFunction> function, 9105 bool JSFunction::CompileLazy(Handle<JSFunction> function,
9082 ClearExceptionFlag flag) { 9106 ClearExceptionFlag flag) {
9083 bool result = true; 9107 bool result = true;
9084 if (function->shared()->is_compiled()) { 9108 if (function->shared()->is_compiled()) {
9085 function->ReplaceCode(function->shared()->code()); 9109 function->ReplaceCode(function->shared()->code());
9086 function->shared()->set_code_age(0); 9110 function->shared()->set_code_age(0);
9087 } else { 9111 } else {
9088 ASSERT(function->shared()->allows_lazy_compilation()); 9112 ASSERT(function->shared()->allows_lazy_compilation());
9089 CompilationInfoWithZone info(function); 9113 CompilationInfoWithZone info(function);
9090 result = CompileLazyHelper(&info, flag); 9114 result = CompileLazyHelper(&info, flag);
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
9710 } 9734 }
9711 9735
9712 9736
9713 int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context) { 9737 int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context) {
9714 ASSERT(native_context->IsNativeContext()); 9738 ASSERT(native_context->IsNativeContext());
9715 if (!FLAG_cache_optimized_code) return -1; 9739 if (!FLAG_cache_optimized_code) return -1;
9716 Object* value = optimized_code_map(); 9740 Object* value = optimized_code_map();
9717 if (!value->IsSmi()) { 9741 if (!value->IsSmi()) {
9718 FixedArray* optimized_code_map = FixedArray::cast(value); 9742 FixedArray* optimized_code_map = FixedArray::cast(value);
9719 int length = optimized_code_map->length(); 9743 int length = optimized_code_map->length();
9720 for (int i = 0; i < length; i += 3) { 9744 for (int i = kEntriesStart; i < length; i += kEntryLength) {
9721 if (optimized_code_map->get(i) == native_context) { 9745 if (optimized_code_map->get(i) == native_context) {
9722 return i + 1; 9746 return i + 1;
9723 } 9747 }
9724 } 9748 }
9725 if (FLAG_trace_opt) { 9749 if (FLAG_trace_opt) {
9726 PrintF("[didn't find optimized code in optimized code map for "); 9750 PrintF("[didn't find optimized code in optimized code map for ");
9727 ShortPrint(); 9751 ShortPrint();
9728 PrintF("]\n"); 9752 PrintF("]\n");
9729 } 9753 }
9730 } 9754 }
(...skipping 5658 matching lines...) Expand 10 before | Expand all | Expand 10 after
15389 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 15413 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
15390 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 15414 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
15391 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 15415 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
15392 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 15416 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
15393 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 15417 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
15394 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 15418 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
15395 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 15419 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
15396 } 15420 }
15397 15421
15398 } } // namespace v8::internal 15422 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-visiting-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698