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 <sstream> | 5 #include <sstream> |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
(...skipping 10015 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10026 DCHECK(shrink_by % kEntryLength == 0); | 10026 DCHECK(shrink_by % kEntryLength == 0); |
10027 DCHECK(shrink_by <= code_map->length() - kEntriesStart); | 10027 DCHECK(shrink_by <= code_map->length() - kEntriesStart); |
10028 // Always trim even when array is cleared because of heap verifier. | 10028 // Always trim even when array is cleared because of heap verifier. |
10029 GetHeap()->RightTrimFixedArray<Heap::FROM_GC>(code_map, shrink_by); | 10029 GetHeap()->RightTrimFixedArray<Heap::FROM_GC>(code_map, shrink_by); |
10030 if (code_map->length() == kEntriesStart) { | 10030 if (code_map->length() == kEntriesStart) { |
10031 ClearOptimizedCodeMap(); | 10031 ClearOptimizedCodeMap(); |
10032 } | 10032 } |
10033 } | 10033 } |
10034 | 10034 |
10035 | 10035 |
| 10036 static void GetMinInobjectSlack(Map* map, void* data) { |
| 10037 int slack = map->unused_property_fields(); |
| 10038 if (*reinterpret_cast<int*>(data) > slack) { |
| 10039 *reinterpret_cast<int*>(data) = slack; |
| 10040 } |
| 10041 } |
| 10042 |
| 10043 |
| 10044 static void ShrinkInstanceSize(Map* map, void* data) { |
| 10045 int slack = *reinterpret_cast<int*>(data); |
| 10046 map->set_inobject_properties(map->inobject_properties() - slack); |
| 10047 map->set_unused_property_fields(map->unused_property_fields() - slack); |
| 10048 map->set_instance_size(map->instance_size() - slack * kPointerSize); |
| 10049 |
| 10050 // Visitor id might depend on the instance size, recalculate it. |
| 10051 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map)); |
| 10052 } |
| 10053 |
| 10054 |
| 10055 void JSFunction::CompleteInobjectSlackTracking() { |
| 10056 DCHECK(has_initial_map()); |
| 10057 Map* map = initial_map(); |
| 10058 |
| 10059 DCHECK(map->counter() >= Map::kSlackTrackingCounterEnd - 1); |
| 10060 map->set_counter(Map::kRetainingCounterStart); |
| 10061 |
| 10062 int slack = map->unused_property_fields(); |
| 10063 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack); |
| 10064 if (slack != 0) { |
| 10065 // Resize the initial map and all maps in its transition tree. |
| 10066 map->TraverseTransitionTree(&ShrinkInstanceSize, &slack); |
| 10067 } |
| 10068 } |
| 10069 |
| 10070 |
10036 void JSObject::OptimizeAsPrototype(Handle<JSObject> object, | 10071 void JSObject::OptimizeAsPrototype(Handle<JSObject> object, |
10037 PrototypeOptimizationMode mode) { | 10072 PrototypeOptimizationMode mode) { |
10038 if (object->IsGlobalObject()) return; | 10073 if (object->IsGlobalObject()) return; |
10039 if (object->IsJSGlobalProxy()) return; | 10074 if (object->IsJSGlobalProxy()) return; |
10040 if (mode == FAST_PROTOTYPE && !object->map()->is_prototype_map()) { | 10075 if (mode == FAST_PROTOTYPE && !object->map()->is_prototype_map()) { |
10041 // First normalize to ensure all JSFunctions are DATA_CONSTANT. | 10076 // First normalize to ensure all JSFunctions are DATA_CONSTANT. |
10042 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0, | 10077 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0, |
10043 "NormalizeAsPrototype"); | 10078 "NormalizeAsPrototype"); |
10044 } | 10079 } |
10045 bool has_just_copied_map = false; | 10080 bool has_just_copied_map = false; |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10217 } | 10252 } |
10218 | 10253 |
10219 // Deoptimize all code that embeds the previous initial map. | 10254 // Deoptimize all code that embeds the previous initial map. |
10220 initial_map->dependent_code()->DeoptimizeDependentCodeGroup( | 10255 initial_map->dependent_code()->DeoptimizeDependentCodeGroup( |
10221 isolate, DependentCode::kInitialMapChangedGroup); | 10256 isolate, DependentCode::kInitialMapChangedGroup); |
10222 } else { | 10257 } else { |
10223 // Put the value in the initial map field until an initial map is | 10258 // Put the value in the initial map field until an initial map is |
10224 // needed. At that point, a new initial map is created and the | 10259 // needed. At that point, a new initial map is created and the |
10225 // prototype is put into the initial map where it belongs. | 10260 // prototype is put into the initial map where it belongs. |
10226 function->set_prototype_or_initial_map(*value); | 10261 function->set_prototype_or_initial_map(*value); |
| 10262 if (value->IsJSObject()) { |
| 10263 // Optimize as prototype to detach it from its transition tree. |
| 10264 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value), |
| 10265 FAST_PROTOTYPE); |
| 10266 } |
10227 } | 10267 } |
10228 isolate->heap()->ClearInstanceofCache(); | 10268 isolate->heap()->ClearInstanceofCache(); |
10229 } | 10269 } |
10230 | 10270 |
10231 | 10271 |
10232 void JSFunction::SetPrototype(Handle<JSFunction> function, | 10272 void JSFunction::SetPrototype(Handle<JSFunction> function, |
10233 Handle<Object> value) { | 10273 Handle<Object> value) { |
10234 DCHECK(function->should_have_prototype()); | 10274 DCHECK(function->should_have_prototype()); |
10235 Handle<Object> construct_prototype = value; | 10275 Handle<Object> construct_prototype = value; |
10236 | 10276 |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10759 // Re-enable optimizations if they were disabled due to opt_count limit. | 10799 // Re-enable optimizations if they were disabled due to opt_count limit. |
10760 set_optimization_disabled(false); | 10800 set_optimization_disabled(false); |
10761 code()->set_optimizable(true); | 10801 code()->set_optimizable(true); |
10762 } | 10802 } |
10763 set_opt_count(0); | 10803 set_opt_count(0); |
10764 set_deopt_count(0); | 10804 set_deopt_count(0); |
10765 } | 10805 } |
10766 } | 10806 } |
10767 | 10807 |
10768 | 10808 |
10769 static void GetMinInobjectSlack(Map* map, void* data) { | |
10770 int slack = map->unused_property_fields(); | |
10771 if (*reinterpret_cast<int*>(data) > slack) { | |
10772 *reinterpret_cast<int*>(data) = slack; | |
10773 } | |
10774 } | |
10775 | |
10776 | |
10777 static void ShrinkInstanceSize(Map* map, void* data) { | |
10778 int slack = *reinterpret_cast<int*>(data); | |
10779 map->set_inobject_properties(map->inobject_properties() - slack); | |
10780 map->set_unused_property_fields(map->unused_property_fields() - slack); | |
10781 map->set_instance_size(map->instance_size() - slack * kPointerSize); | |
10782 | |
10783 // Visitor id might depend on the instance size, recalculate it. | |
10784 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map)); | |
10785 } | |
10786 | |
10787 | |
10788 void JSFunction::CompleteInobjectSlackTracking() { | |
10789 DCHECK(has_initial_map()); | |
10790 Map* map = initial_map(); | |
10791 | |
10792 DCHECK(map->counter() >= Map::kSlackTrackingCounterEnd - 1); | |
10793 map->set_counter(Map::kRetainingCounterStart); | |
10794 | |
10795 int slack = map->unused_property_fields(); | |
10796 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack); | |
10797 if (slack != 0) { | |
10798 // Resize the initial map and all maps in its transition tree. | |
10799 map->TraverseTransitionTree(&ShrinkInstanceSize, &slack); | |
10800 } | |
10801 } | |
10802 | |
10803 | |
10804 int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context, | 10809 int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context, |
10805 BailoutId osr_ast_id) { | 10810 BailoutId osr_ast_id) { |
10806 DisallowHeapAllocation no_gc; | 10811 DisallowHeapAllocation no_gc; |
10807 DCHECK(native_context->IsNativeContext()); | 10812 DCHECK(native_context->IsNativeContext()); |
10808 if (!FLAG_cache_optimized_code) return -1; | 10813 if (!FLAG_cache_optimized_code) return -1; |
10809 Object* value = optimized_code_map(); | 10814 Object* value = optimized_code_map(); |
10810 if (!value->IsSmi()) { | 10815 if (!value->IsSmi()) { |
10811 FixedArray* optimized_code_map = FixedArray::cast(value); | 10816 FixedArray* optimized_code_map = FixedArray::cast(value); |
10812 int length = optimized_code_map->length(); | 10817 int length = optimized_code_map->length(); |
10813 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); | 10818 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); |
(...skipping 6487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17301 CompilationInfo* info) { | 17306 CompilationInfo* info) { |
17302 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( | 17307 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
17303 handle(cell->dependent_code(), info->isolate()), | 17308 handle(cell->dependent_code(), info->isolate()), |
17304 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); | 17309 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); |
17305 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 17310 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
17306 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 17311 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
17307 cell, info->zone()); | 17312 cell, info->zone()); |
17308 } | 17313 } |
17309 | 17314 |
17310 } } // namespace v8::internal | 17315 } } // namespace v8::internal |
OLD | NEW |