OLD | NEW |
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 2468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2479 if (is_deprecated()) return; | 2479 if (is_deprecated()) return; |
2480 if (HasTransitionArray()) { | 2480 if (HasTransitionArray()) { |
2481 TransitionArray* transitions = this->transitions(); | 2481 TransitionArray* transitions = this->transitions(); |
2482 for (int i = 0; i < transitions->number_of_transitions(); i++) { | 2482 for (int i = 0; i < transitions->number_of_transitions(); i++) { |
2483 transitions->GetTarget(i)->DeprecateTransitionTree(); | 2483 transitions->GetTarget(i)->DeprecateTransitionTree(); |
2484 } | 2484 } |
2485 } | 2485 } |
2486 deprecate(); | 2486 deprecate(); |
2487 dependent_code()->DeoptimizeDependentCodeGroup( | 2487 dependent_code()->DeoptimizeDependentCodeGroup( |
2488 GetIsolate(), DependentCode::kTransitionGroup); | 2488 GetIsolate(), DependentCode::kTransitionGroup); |
2489 dependent_code()->DeoptimizeDependentCodeGroup( | 2489 NotifyLeafMapLayoutChange(); |
2490 GetIsolate(), DependentCode::kPrototypeCheckGroup); | |
2491 } | 2490 } |
2492 | 2491 |
2493 | 2492 |
2494 // Invalidates a transition target at |key|, and installs |new_descriptors| over | 2493 // Invalidates a transition target at |key|, and installs |new_descriptors| over |
2495 // the current instance_descriptors to ensure proper sharing of descriptor | 2494 // the current instance_descriptors to ensure proper sharing of descriptor |
2496 // arrays. | 2495 // arrays. |
2497 void Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors) { | 2496 void Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors) { |
2498 if (HasTransitionArray()) { | 2497 if (HasTransitionArray()) { |
2499 TransitionArray* transitions = this->transitions(); | 2498 TransitionArray* transitions = this->transitions(); |
2500 int transition = transitions->Search(key); | 2499 int transition = transitions->Search(key); |
(...skipping 1441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3942 break; | 3941 break; |
3943 } | 3942 } |
3944 case HANDLER: | 3943 case HANDLER: |
3945 case NONEXISTENT: | 3944 case NONEXISTENT: |
3946 UNREACHABLE(); | 3945 UNREACHABLE(); |
3947 } | 3946 } |
3948 | 3947 |
3949 Handle<Object> hresult; | 3948 Handle<Object> hresult; |
3950 if (!result->ToHandle(&hresult, isolate)) return result; | 3949 if (!result->ToHandle(&hresult, isolate)) return result; |
3951 | 3950 |
3952 if (FLAG_harmony_observation && map()->is_observed()) { | 3951 if (FLAG_harmony_observation && self->map()->is_observed()) { |
3953 if (lookup->IsTransition()) { | 3952 if (lookup->IsTransition()) { |
3954 EnqueueChangeRecord(self, "new", name, old_value); | 3953 EnqueueChangeRecord(self, "new", name, old_value); |
3955 } else { | 3954 } else { |
3956 LookupResult new_lookup(isolate); | 3955 LookupResult new_lookup(isolate); |
3957 self->LocalLookup(*name, &new_lookup, true); | 3956 self->LocalLookup(*name, &new_lookup, true); |
3958 if (new_lookup.IsDataProperty()) { | 3957 if (new_lookup.IsDataProperty()) { |
3959 Handle<Object> new_value = Object::GetProperty(self, name); | 3958 Handle<Object> new_value = Object::GetProperty(self, name); |
3960 if (!new_value->SameValue(*old_value)) { | 3959 if (!new_value->SameValue(*old_value)) { |
3961 EnqueueChangeRecord(self, "updated", name, old_value); | 3960 EnqueueChangeRecord(self, "updated", name, old_value); |
3962 } | 3961 } |
(...skipping 2525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6488 | 6487 |
6489 result->set_prototype(prototype()); | 6488 result->set_prototype(prototype()); |
6490 result->set_constructor(constructor()); | 6489 result->set_constructor(constructor()); |
6491 result->set_bit_field(bit_field()); | 6490 result->set_bit_field(bit_field()); |
6492 result->set_bit_field2(bit_field2()); | 6491 result->set_bit_field2(bit_field2()); |
6493 int new_bit_field3 = bit_field3(); | 6492 int new_bit_field3 = bit_field3(); |
6494 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true); | 6493 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true); |
6495 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0); | 6494 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0); |
6496 new_bit_field3 = EnumLengthBits::update(new_bit_field3, kInvalidEnumCache); | 6495 new_bit_field3 = EnumLengthBits::update(new_bit_field3, kInvalidEnumCache); |
6497 new_bit_field3 = Deprecated::update(new_bit_field3, false); | 6496 new_bit_field3 = Deprecated::update(new_bit_field3, false); |
| 6497 new_bit_field3 = IsUnstable::update(new_bit_field3, false); |
6498 result->set_bit_field3(new_bit_field3); | 6498 result->set_bit_field3(new_bit_field3); |
6499 return result; | 6499 return result; |
6500 } | 6500 } |
6501 | 6501 |
6502 | 6502 |
6503 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode, | 6503 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode, |
6504 NormalizedMapSharingMode sharing) { | 6504 NormalizedMapSharingMode sharing) { |
6505 int new_instance_size = instance_size(); | 6505 int new_instance_size = instance_size(); |
6506 if (mode == CLEAR_INOBJECT_PROPERTIES) { | 6506 if (mode == CLEAR_INOBJECT_PROPERTIES) { |
6507 new_instance_size -= inobject_properties() * kPointerSize; | 6507 new_instance_size -= inobject_properties() * kPointerSize; |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7016 | 7016 |
7017 Map* Next() { | 7017 Map* Next() { |
7018 ASSERT(IsIterating()); | 7018 ASSERT(IsIterating()); |
7019 int index = Smi::cast(*TransitionArrayHeader())->value(); | 7019 int index = Smi::cast(*TransitionArrayHeader())->value(); |
7020 int number_of_transitions = transition_array_->number_of_transitions(); | 7020 int number_of_transitions = transition_array_->number_of_transitions(); |
7021 while (index < number_of_transitions) { | 7021 while (index < number_of_transitions) { |
7022 *TransitionArrayHeader() = Smi::FromInt(index + 1); | 7022 *TransitionArrayHeader() = Smi::FromInt(index + 1); |
7023 return transition_array_->GetTarget(index); | 7023 return transition_array_->GetTarget(index); |
7024 } | 7024 } |
7025 | 7025 |
7026 if (index == number_of_transitions && | |
7027 transition_array_->HasElementsTransition()) { | |
7028 Map* elements_transition = transition_array_->elements_transition(); | |
7029 *TransitionArrayHeader() = Smi::FromInt(index + 1); | |
7030 return elements_transition; | |
7031 } | |
7032 *TransitionArrayHeader() = transition_array_->GetHeap()->fixed_array_map(); | 7026 *TransitionArrayHeader() = transition_array_->GetHeap()->fixed_array_map(); |
7033 return NULL; | 7027 return NULL; |
7034 } | 7028 } |
7035 | 7029 |
7036 private: | 7030 private: |
7037 Object** TransitionArrayHeader() { | 7031 Object** TransitionArrayHeader() { |
7038 return HeapObject::RawField(transition_array_, TransitionArray::kMapOffset); | 7032 return HeapObject::RawField(transition_array_, TransitionArray::kMapOffset); |
7039 } | 7033 } |
7040 | 7034 |
7041 TransitionArray* transition_array_; | 7035 TransitionArray* transition_array_; |
(...skipping 2096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9138 t->SetKey(transition_index, key); | 9132 t->SetKey(transition_index, key); |
9139 Object** key_slot = t->GetKeySlot(transition_index); | 9133 Object** key_slot = t->GetKeySlot(transition_index); |
9140 collector->RecordSlot(key_slot, key_slot, key); | 9134 collector->RecordSlot(key_slot, key_slot, key); |
9141 // Target slots do not need to be recorded since maps are not compacted. | 9135 // Target slots do not need to be recorded since maps are not compacted. |
9142 t->SetTarget(transition_index, t->GetTarget(i)); | 9136 t->SetTarget(transition_index, t->GetTarget(i)); |
9143 } | 9137 } |
9144 transition_index++; | 9138 transition_index++; |
9145 } | 9139 } |
9146 } | 9140 } |
9147 | 9141 |
9148 if (t->HasElementsTransition() && | 9142 // If there are no transitions to be cleared, return. |
9149 ClearBackPointer(heap, t->elements_transition())) { | 9143 // TODO(verwaest) Should be an assert, otherwise back pointers are not |
9150 if (t->elements_transition()->instance_descriptors() == descriptors) { | 9144 // properly cleared. |
9151 descriptors_owner_died = true; | 9145 if (transition_index == t->number_of_transitions()) return; |
9152 } | |
9153 t->ClearElementsTransition(); | |
9154 } else { | |
9155 // If there are no transitions to be cleared, return. | |
9156 // TODO(verwaest) Should be an assert, otherwise back pointers are not | |
9157 // properly cleared. | |
9158 if (transition_index == t->number_of_transitions()) return; | |
9159 } | |
9160 | 9146 |
9161 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 9147 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
9162 | 9148 |
9163 if (descriptors_owner_died) { | 9149 if (descriptors_owner_died) { |
9164 if (number_of_own_descriptors > 0) { | 9150 if (number_of_own_descriptors > 0) { |
9165 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors); | 9151 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors); |
9166 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); | 9152 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); |
9167 } else { | 9153 } else { |
9168 ASSERT(descriptors == GetHeap()->empty_descriptor_array()); | 9154 ASSERT(descriptors == GetHeap()->empty_descriptor_array()); |
9169 } | 9155 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9227 v->VisitCodeEntry(this->address() + kCodeEntryOffset); | 9213 v->VisitCodeEntry(this->address() + kCodeEntryOffset); |
9228 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); | 9214 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); |
9229 } | 9215 } |
9230 | 9216 |
9231 | 9217 |
9232 void JSFunction::MarkForLazyRecompilation() { | 9218 void JSFunction::MarkForLazyRecompilation() { |
9233 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints()); | 9219 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints()); |
9234 ASSERT(!IsOptimized()); | 9220 ASSERT(!IsOptimized()); |
9235 ASSERT(shared()->allows_lazy_compilation() || | 9221 ASSERT(shared()->allows_lazy_compilation() || |
9236 code()->optimizable()); | 9222 code()->optimizable()); |
9237 ASSERT(!shared()->is_generator()); | |
9238 set_code_no_write_barrier( | 9223 set_code_no_write_barrier( |
9239 GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile)); | 9224 GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile)); |
9240 // No write barrier required, since the builtin is part of the root set. | 9225 // No write barrier required, since the builtin is part of the root set. |
9241 } | 9226 } |
9242 | 9227 |
9243 | 9228 |
9244 void JSFunction::MarkForParallelRecompilation() { | 9229 void JSFunction::MarkForParallelRecompilation() { |
9245 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints()); | 9230 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints()); |
9246 ASSERT(!IsOptimized()); | 9231 ASSERT(!IsOptimized()); |
9247 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); | 9232 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); |
9248 ASSERT(!shared()->is_generator()); | 9233 if (!FLAG_parallel_recompilation) { |
9249 ASSERT(FLAG_parallel_recompilation); | 9234 JSFunction::MarkForLazyRecompilation(); |
| 9235 return; |
| 9236 } |
9250 if (FLAG_trace_parallel_recompilation) { | 9237 if (FLAG_trace_parallel_recompilation) { |
9251 PrintF(" ** Marking "); | 9238 PrintF(" ** Marking "); |
9252 PrintName(); | 9239 PrintName(); |
9253 PrintF(" for parallel recompilation.\n"); | 9240 PrintF(" for parallel recompilation.\n"); |
9254 } | 9241 } |
9255 set_code_no_write_barrier( | 9242 set_code_no_write_barrier( |
9256 GetIsolate()->builtins()->builtin(Builtins::kParallelRecompile)); | 9243 GetIsolate()->builtins()->builtin(Builtins::kParallelRecompile)); |
9257 // No write barrier required, since the builtin is part of the root set. | 9244 // No write barrier required, since the builtin is part of the root set. |
9258 } | 9245 } |
9259 | 9246 |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9810 // TODO(3025757): In case the recompiled isn't equivalent to the | 9797 // TODO(3025757): In case the recompiled isn't equivalent to the |
9811 // old code, we have to replace it. We should try to avoid this | 9798 // old code, we have to replace it. We should try to avoid this |
9812 // altogether because it flushes valuable type feedback by | 9799 // altogether because it flushes valuable type feedback by |
9813 // effectively resetting all IC state. | 9800 // effectively resetting all IC state. |
9814 ReplaceCode(recompiled); | 9801 ReplaceCode(recompiled); |
9815 } | 9802 } |
9816 ASSERT(has_deoptimization_support()); | 9803 ASSERT(has_deoptimization_support()); |
9817 } | 9804 } |
9818 | 9805 |
9819 | 9806 |
9820 void SharedFunctionInfo::DisableOptimization(const char* reason) { | 9807 void SharedFunctionInfo::DisableOptimization(BailoutReason reason) { |
9821 // Disable optimization for the shared function info and mark the | 9808 // Disable optimization for the shared function info and mark the |
9822 // code as non-optimizable. The marker on the shared function info | 9809 // code as non-optimizable. The marker on the shared function info |
9823 // is there because we flush non-optimized code thereby loosing the | 9810 // is there because we flush non-optimized code thereby loosing the |
9824 // non-optimizable information for the code. When the code is | 9811 // non-optimizable information for the code. When the code is |
9825 // regenerated and set on the shared function info it is marked as | 9812 // regenerated and set on the shared function info it is marked as |
9826 // non-optimizable if optimization is disabled for the shared | 9813 // non-optimizable if optimization is disabled for the shared |
9827 // function info. | 9814 // function info. |
9828 set_optimization_disabled(true); | 9815 set_optimization_disabled(true); |
9829 // Code should be the lazy compilation stub or else unoptimized. If the | 9816 // Code should be the lazy compilation stub or else unoptimized. If the |
9830 // latter, disable optimization for the code too. | 9817 // latter, disable optimization for the code too. |
9831 ASSERT(code()->kind() == Code::FUNCTION || code()->kind() == Code::BUILTIN); | 9818 ASSERT(code()->kind() == Code::FUNCTION || code()->kind() == Code::BUILTIN); |
9832 if (code()->kind() == Code::FUNCTION) { | 9819 if (code()->kind() == Code::FUNCTION) { |
9833 code()->set_optimizable(false); | 9820 code()->set_optimizable(false); |
9834 } | 9821 } |
9835 if (FLAG_trace_opt) { | 9822 if (FLAG_trace_opt) { |
9836 PrintF("[disabled optimization for "); | 9823 PrintF("[disabled optimization for "); |
9837 ShortPrint(); | 9824 ShortPrint(); |
9838 PrintF(", reason: %s]\n", reason); | 9825 PrintF(", reason: %s]\n", GetBailoutReason(reason)); |
9839 } | 9826 } |
9840 } | 9827 } |
9841 | 9828 |
9842 | 9829 |
9843 bool SharedFunctionInfo::VerifyBailoutId(BailoutId id) { | 9830 bool SharedFunctionInfo::VerifyBailoutId(BailoutId id) { |
9844 ASSERT(!id.IsNone()); | 9831 ASSERT(!id.IsNone()); |
9845 Code* unoptimized = code(); | 9832 Code* unoptimized = code(); |
9846 DeoptimizationOutputData* data = | 9833 DeoptimizationOutputData* data = |
9847 DeoptimizationOutputData::cast(unoptimized->deoptimization_data()); | 9834 DeoptimizationOutputData::cast(unoptimized->deoptimization_data()); |
9848 unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this); | 9835 unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this); |
(...skipping 6121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15970 | 15957 |
15971 | 15958 |
15972 void PropertyCell::AddDependentCode(Handle<Code> code) { | 15959 void PropertyCell::AddDependentCode(Handle<Code> code) { |
15973 Handle<DependentCode> codes = DependentCode::Insert( | 15960 Handle<DependentCode> codes = DependentCode::Insert( |
15974 Handle<DependentCode>(dependent_code()), | 15961 Handle<DependentCode>(dependent_code()), |
15975 DependentCode::kPropertyCellChangedGroup, code); | 15962 DependentCode::kPropertyCellChangedGroup, code); |
15976 if (*codes != dependent_code()) set_dependent_code(*codes); | 15963 if (*codes != dependent_code()) set_dependent_code(*codes); |
15977 } | 15964 } |
15978 | 15965 |
15979 | 15966 |
| 15967 const char* GetBailoutReason(BailoutReason reason) { |
| 15968 ASSERT(reason < kLastErrorMessage); |
| 15969 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 15970 static const char* error_messages_[] = { |
| 15971 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 15972 }; |
| 15973 #undef ERROR_MESSAGES_TEXTS |
| 15974 return error_messages_[reason]; |
| 15975 } |
| 15976 |
| 15977 |
15980 } } // namespace v8::internal | 15978 } } // namespace v8::internal |
OLD | NEW |