| 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 |