| 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 27 matching lines...) Expand all Loading... |
| 38 #include "debug.h" | 38 #include "debug.h" |
| 39 #include "deoptimizer.h" | 39 #include "deoptimizer.h" |
| 40 #include "date.h" | 40 #include "date.h" |
| 41 #include "elements.h" | 41 #include "elements.h" |
| 42 #include "execution.h" | 42 #include "execution.h" |
| 43 #include "full-codegen.h" | 43 #include "full-codegen.h" |
| 44 #include "hydrogen.h" | 44 #include "hydrogen.h" |
| 45 #include "isolate-inl.h" | 45 #include "isolate-inl.h" |
| 46 #include "log.h" | 46 #include "log.h" |
| 47 #include "objects-inl.h" | 47 #include "objects-inl.h" |
| 48 #include "objects-visiting.h" | |
| 49 #include "objects-visiting-inl.h" | 48 #include "objects-visiting-inl.h" |
| 50 #include "macro-assembler.h" | 49 #include "macro-assembler.h" |
| 51 #include "mark-compact.h" | 50 #include "mark-compact.h" |
| 52 #include "safepoint-table.h" | 51 #include "safepoint-table.h" |
| 53 #include "string-stream.h" | 52 #include "string-stream.h" |
| 54 #include "utils.h" | 53 #include "utils.h" |
| 55 | 54 |
| 56 #ifdef ENABLE_DISASSEMBLER | 55 #ifdef ENABLE_DISASSEMBLER |
| 57 #include "disasm.h" | 56 #include "disasm.h" |
| 58 #include "disassembler.h" | 57 #include "disassembler.h" |
| (...skipping 5858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5917 ASSERT(!curr->HasNamedInterceptor()); | 5916 ASSERT(!curr->HasNamedInterceptor()); |
| 5918 ASSERT(!curr->HasIndexedInterceptor()); | 5917 ASSERT(!curr->HasIndexedInterceptor()); |
| 5919 ASSERT(!curr->IsAccessCheckNeeded()); | 5918 ASSERT(!curr->IsAccessCheckNeeded()); |
| 5920 if (curr->NumberOfEnumElements() > 0) return false; | 5919 if (curr->NumberOfEnumElements() > 0) return false; |
| 5921 if (curr != this && enum_length != 0) return false; | 5920 if (curr != this && enum_length != 0) return false; |
| 5922 } | 5921 } |
| 5923 return true; | 5922 return true; |
| 5924 } | 5923 } |
| 5925 | 5924 |
| 5926 | 5925 |
| 5926 static bool FilterKey(Object* key, PropertyAttributes filter) { |
| 5927 if ((filter & SYMBOLIC) && key->IsSymbol()) { |
| 5928 return true; |
| 5929 } |
| 5930 |
| 5931 if ((filter & PRIVATE_SYMBOL) && |
| 5932 key->IsSymbol() && Symbol::cast(key)->is_private()) { |
| 5933 return true; |
| 5934 } |
| 5935 |
| 5936 if ((filter & STRING) && !key->IsSymbol()) { |
| 5937 return true; |
| 5938 } |
| 5939 |
| 5940 return false; |
| 5941 } |
| 5942 |
| 5943 |
| 5927 int Map::NumberOfDescribedProperties(DescriptorFlag which, | 5944 int Map::NumberOfDescribedProperties(DescriptorFlag which, |
| 5928 PropertyAttributes filter) { | 5945 PropertyAttributes filter) { |
| 5929 int result = 0; | 5946 int result = 0; |
| 5930 DescriptorArray* descs = instance_descriptors(); | 5947 DescriptorArray* descs = instance_descriptors(); |
| 5931 int limit = which == ALL_DESCRIPTORS | 5948 int limit = which == ALL_DESCRIPTORS |
| 5932 ? descs->number_of_descriptors() | 5949 ? descs->number_of_descriptors() |
| 5933 : NumberOfOwnDescriptors(); | 5950 : NumberOfOwnDescriptors(); |
| 5934 for (int i = 0; i < limit; i++) { | 5951 for (int i = 0; i < limit; i++) { |
| 5935 if ((descs->GetDetails(i).attributes() & filter) == 0 && | 5952 if ((descs->GetDetails(i).attributes() & filter) == 0 && |
| 5936 ((filter & SYMBOLIC) == 0 || !descs->GetKey(i)->IsSymbol())) { | 5953 !FilterKey(descs->GetKey(i), filter)) { |
| 5937 result++; | 5954 result++; |
| 5938 } | 5955 } |
| 5939 } | 5956 } |
| 5940 return result; | 5957 return result; |
| 5941 } | 5958 } |
| 5942 | 5959 |
| 5943 | 5960 |
| 5944 int Map::NextFreePropertyIndex() { | 5961 int Map::NextFreePropertyIndex() { |
| 5945 int max_index = -1; | 5962 int max_index = -1; |
| 5946 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 5963 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
| (...skipping 3230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9177 if (Marking::IsBlack(Marking::MarkBitFrom(start_of_string))) { | 9194 if (Marking::IsBlack(Marking::MarkBitFrom(start_of_string))) { |
| 9178 MemoryChunk::IncrementLiveBytesFromMutator(start_of_string, -delta); | 9195 MemoryChunk::IncrementLiveBytesFromMutator(start_of_string, -delta); |
| 9179 } | 9196 } |
| 9180 | 9197 |
| 9181 | 9198 |
| 9182 if (new_length == 0) return heap->isolate()->factory()->empty_string(); | 9199 if (new_length == 0) return heap->isolate()->factory()->empty_string(); |
| 9183 return string; | 9200 return string; |
| 9184 } | 9201 } |
| 9185 | 9202 |
| 9186 | 9203 |
| 9187 AllocationMemento* AllocationMemento::FindForHeapObject(HeapObject* object, | |
| 9188 bool in_GC) { | |
| 9189 // AllocationMemento objects are only allocated immediately after objects in | |
| 9190 // NewSpace. Detecting whether a memento is present involves carefully | |
| 9191 // checking the object immediately after the current object (if there is one) | |
| 9192 // to see if it's an AllocationMemento. | |
| 9193 ASSERT(object->GetHeap()->InNewSpace(object)); | |
| 9194 if (FLAG_track_allocation_sites) { | |
| 9195 Address ptr_end = (reinterpret_cast<Address>(object) - kHeapObjectTag) + | |
| 9196 object->Size(); | |
| 9197 Address top; | |
| 9198 if (in_GC) { | |
| 9199 top = object->GetHeap()->new_space()->FromSpacePageHigh(); | |
| 9200 } else { | |
| 9201 top = object->GetHeap()->NewSpaceTop(); | |
| 9202 } | |
| 9203 if ((ptr_end + AllocationMemento::kSize) <= top) { | |
| 9204 // There is room in newspace for allocation info. Do we have some? | |
| 9205 Map** possible_allocation_memento_map = | |
| 9206 reinterpret_cast<Map**>(ptr_end); | |
| 9207 if (*possible_allocation_memento_map == | |
| 9208 object->GetHeap()->allocation_memento_map()) { | |
| 9209 AllocationMemento* memento = AllocationMemento::cast( | |
| 9210 reinterpret_cast<Object*>(ptr_end + kHeapObjectTag)); | |
| 9211 if (memento->IsValid()) { | |
| 9212 return memento; | |
| 9213 } | |
| 9214 } | |
| 9215 } | |
| 9216 } | |
| 9217 return NULL; | |
| 9218 } | |
| 9219 | |
| 9220 | |
| 9221 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { | 9204 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { |
| 9222 // For array indexes mix the length into the hash as an array index could | 9205 // For array indexes mix the length into the hash as an array index could |
| 9223 // be zero. | 9206 // be zero. |
| 9224 ASSERT(length > 0); | 9207 ASSERT(length > 0); |
| 9225 ASSERT(length <= String::kMaxArrayIndexSize); | 9208 ASSERT(length <= String::kMaxArrayIndexSize); |
| 9226 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < | 9209 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < |
| 9227 (1 << String::kArrayIndexValueBits)); | 9210 (1 << String::kArrayIndexValueBits)); |
| 9228 | 9211 |
| 9229 value <<= String::kHashShift; | 9212 value <<= String::kHashShift; |
| 9230 value |= length << String::kArrayIndexHashLengthShift; | 9213 value |= length << String::kArrayIndexHashLengthShift; |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9453 int properties = mode == CLEAR_INOBJECT_PROPERTIES | 9436 int properties = mode == CLEAR_INOBJECT_PROPERTIES |
| 9454 ? 0 : other->inobject_properties(); | 9437 ? 0 : other->inobject_properties(); |
| 9455 return CheckEquivalent(this, other) && inobject_properties() == properties; | 9438 return CheckEquivalent(this, other) && inobject_properties() == properties; |
| 9456 } | 9439 } |
| 9457 | 9440 |
| 9458 | 9441 |
| 9459 void ConstantPoolArray::ConstantPoolIterateBody(ObjectVisitor* v) { | 9442 void ConstantPoolArray::ConstantPoolIterateBody(ObjectVisitor* v) { |
| 9460 if (count_of_ptr_entries() > 0) { | 9443 if (count_of_ptr_entries() > 0) { |
| 9461 int first_ptr_offset = OffsetOfElementAt(first_ptr_index()); | 9444 int first_ptr_offset = OffsetOfElementAt(first_ptr_index()); |
| 9462 int last_ptr_offset = | 9445 int last_ptr_offset = |
| 9463 OffsetOfElementAt(first_ptr_index() + count_of_ptr_entries()); | 9446 OffsetOfElementAt(first_ptr_index() + count_of_ptr_entries() - 1); |
| 9464 v->VisitPointers( | 9447 v->VisitPointers( |
| 9465 HeapObject::RawField(this, first_ptr_offset), | 9448 HeapObject::RawField(this, first_ptr_offset), |
| 9466 HeapObject::RawField(this, last_ptr_offset)); | 9449 HeapObject::RawField(this, last_ptr_offset)); |
| 9467 } | 9450 } |
| 9468 } | 9451 } |
| 9469 | 9452 |
| 9470 | 9453 |
| 9471 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { | 9454 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { |
| 9472 // Iterate over all fields in the body but take care in dealing with | 9455 // Iterate over all fields in the body but take care in dealing with |
| 9473 // the code entry. | 9456 // the code entry. |
| (...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10520 Object* object = info->target_object(); | 10503 Object* object = info->target_object(); |
| 10521 if (object->IsMap()) maps->Add(handle(Map::cast(object))); | 10504 if (object->IsMap()) maps->Add(handle(Map::cast(object))); |
| 10522 } | 10505 } |
| 10523 } | 10506 } |
| 10524 | 10507 |
| 10525 | 10508 |
| 10526 void Code::FindAllTypes(TypeHandleList* types) { | 10509 void Code::FindAllTypes(TypeHandleList* types) { |
| 10527 ASSERT(is_inline_cache_stub()); | 10510 ASSERT(is_inline_cache_stub()); |
| 10528 DisallowHeapAllocation no_allocation; | 10511 DisallowHeapAllocation no_allocation; |
| 10529 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 10512 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
| 10530 Isolate* isolate = GetIsolate(); | |
| 10531 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10513 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
| 10532 RelocInfo* info = it.rinfo(); | 10514 RelocInfo* info = it.rinfo(); |
| 10533 Object* object = info->target_object(); | 10515 Object* object = info->target_object(); |
| 10534 if (object->IsMap()) { | 10516 if (object->IsMap()) { |
| 10535 Handle<Map> map(Map::cast(object)); | 10517 Handle<Map> map(Map::cast(object)); |
| 10536 types->Add(handle(IC::MapToType(map), isolate)); | 10518 types->Add(IC::MapToType(map)); |
| 10537 } | 10519 } |
| 10538 } | 10520 } |
| 10539 } | 10521 } |
| 10540 | 10522 |
| 10541 | 10523 |
| 10542 void Code::ReplaceFirstMap(Map* replace_with) { | 10524 void Code::ReplaceFirstMap(Map* replace_with) { |
| 10543 ReplaceNthObject(1, GetHeap()->meta_map(), replace_with); | 10525 ReplaceNthObject(1, GetHeap()->meta_map(), replace_with); |
| 10544 } | 10526 } |
| 10545 | 10527 |
| 10546 | 10528 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10610 | 10592 |
| 10611 | 10593 |
| 10612 void Code::ClearInlineCaches(Code::Kind kind) { | 10594 void Code::ClearInlineCaches(Code::Kind kind) { |
| 10613 ClearInlineCaches(&kind); | 10595 ClearInlineCaches(&kind); |
| 10614 } | 10596 } |
| 10615 | 10597 |
| 10616 | 10598 |
| 10617 void Code::ClearInlineCaches(Code::Kind* kind) { | 10599 void Code::ClearInlineCaches(Code::Kind* kind) { |
| 10618 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | | 10600 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
| 10619 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | | 10601 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | |
| 10620 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) | | 10602 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID); |
| 10621 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT); | |
| 10622 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10603 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
| 10623 RelocInfo* info = it.rinfo(); | 10604 RelocInfo* info = it.rinfo(); |
| 10624 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); | 10605 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); |
| 10625 if (target->is_inline_cache_stub()) { | 10606 if (target->is_inline_cache_stub()) { |
| 10626 if (kind == NULL || *kind == target->kind()) { | 10607 if (kind == NULL || *kind == target->kind()) { |
| 10627 IC::Clear(this->GetIsolate(), info->pc()); | 10608 IC::Clear(this->GetIsolate(), info->pc()); |
| 10628 } | 10609 } |
| 10629 } | 10610 } |
| 10630 } | 10611 } |
| 10631 } | 10612 } |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10836 Address code_start_address = instruction_start(); | 10817 Address code_start_address = instruction_start(); |
| 10837 for (int i = 0; i < deopt_data->DeoptCount(); i++) { | 10818 for (int i = 0; i < deopt_data->DeoptCount(); i++) { |
| 10838 if (deopt_data->Pc(i)->value() == -1) continue; | 10819 if (deopt_data->Pc(i)->value() == -1) continue; |
| 10839 Address address = code_start_address + deopt_data->Pc(i)->value(); | 10820 Address address = code_start_address + deopt_data->Pc(i)->value(); |
| 10840 if (address == pc) return true; | 10821 if (address == pc) return true; |
| 10841 } | 10822 } |
| 10842 return false; | 10823 return false; |
| 10843 } | 10824 } |
| 10844 | 10825 |
| 10845 | 10826 |
| 10827 bool Code::IsContextual() { |
| 10828 ASSERT(is_inline_cache_stub()); |
| 10829 Kind kind = this->kind(); |
| 10830 if (kind == STORE_IC || kind == LOAD_IC || kind == CALL_IC) { |
| 10831 ExtraICState extra_state = extra_ic_state(); |
| 10832 return IC::GetContextualMode(extra_state) == CONTEXTUAL; |
| 10833 } |
| 10834 return false; |
| 10835 } |
| 10836 |
| 10837 |
| 10846 // Identify kind of code. | 10838 // Identify kind of code. |
| 10847 const char* Code::Kind2String(Kind kind) { | 10839 const char* Code::Kind2String(Kind kind) { |
| 10848 switch (kind) { | 10840 switch (kind) { |
| 10849 #define CASE(name) case name: return #name; | 10841 #define CASE(name) case name: return #name; |
| 10850 CODE_KIND_LIST(CASE) | 10842 CODE_KIND_LIST(CASE) |
| 10851 #undef CASE | 10843 #undef CASE |
| 10852 case NUMBER_OF_KINDS: break; | 10844 case NUMBER_OF_KINDS: break; |
| 10853 } | 10845 } |
| 10854 UNREACHABLE(); | 10846 UNREACHABLE(); |
| 10855 return NULL; | 10847 return NULL; |
| (...skipping 1904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12760 void JSObject::TransitionElementsKind(Handle<JSObject> object, | 12752 void JSObject::TransitionElementsKind(Handle<JSObject> object, |
| 12761 ElementsKind to_kind) { | 12753 ElementsKind to_kind) { |
| 12762 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), | 12754 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), |
| 12763 object->TransitionElementsKind(to_kind)); | 12755 object->TransitionElementsKind(to_kind)); |
| 12764 } | 12756 } |
| 12765 | 12757 |
| 12766 | 12758 |
| 12767 const double AllocationSite::kPretenureRatio = 0.60; | 12759 const double AllocationSite::kPretenureRatio = 0.60; |
| 12768 | 12760 |
| 12769 | 12761 |
| 12762 void AllocationSite::ResetPretenureDecision() { |
| 12763 dependent_code()->DeoptimizeDependentCodeGroup( |
| 12764 GetIsolate(), |
| 12765 DependentCode::kAllocationSiteTenuringChangedGroup); |
| 12766 set_pretenure_decision(kUndecided); |
| 12767 set_memento_found_count(0); |
| 12768 set_memento_create_count(0); |
| 12769 } |
| 12770 |
| 12771 |
| 12772 PretenureFlag AllocationSite::GetPretenureMode() { |
| 12773 PretenureDecision mode = pretenure_decision(); |
| 12774 // Zombie objects "decide" to be untenured. |
| 12775 return (mode == kTenure && GetHeap()->GetPretenureMode() == TENURED) |
| 12776 ? TENURED : NOT_TENURED; |
| 12777 } |
| 12778 |
| 12779 |
| 12770 bool AllocationSite::IsNestedSite() { | 12780 bool AllocationSite::IsNestedSite() { |
| 12771 ASSERT(FLAG_trace_track_allocation_sites); | 12781 ASSERT(FLAG_trace_track_allocation_sites); |
| 12772 Object* current = GetHeap()->allocation_sites_list(); | 12782 Object* current = GetHeap()->allocation_sites_list(); |
| 12773 while (current != NULL && current->IsAllocationSite()) { | 12783 while (current->IsAllocationSite()) { |
| 12774 AllocationSite* current_site = AllocationSite::cast(current); | 12784 AllocationSite* current_site = AllocationSite::cast(current); |
| 12775 if (current_site->nested_site() == this) { | 12785 if (current_site->nested_site() == this) { |
| 12776 return true; | 12786 return true; |
| 12777 } | 12787 } |
| 12778 current = current_site->weak_next(); | 12788 current = current_site->weak_next(); |
| 12779 } | 12789 } |
| 12780 return false; | 12790 return false; |
| 12781 } | 12791 } |
| 12782 | 12792 |
| 12783 | 12793 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12827 } | 12837 } |
| 12828 SetElementsKind(to_kind); | 12838 SetElementsKind(to_kind); |
| 12829 dependent_code()->DeoptimizeDependentCodeGroup( | 12839 dependent_code()->DeoptimizeDependentCodeGroup( |
| 12830 isolate, DependentCode::kAllocationSiteTransitionChangedGroup); | 12840 isolate, DependentCode::kAllocationSiteTransitionChangedGroup); |
| 12831 } | 12841 } |
| 12832 } | 12842 } |
| 12833 return this; | 12843 return this; |
| 12834 } | 12844 } |
| 12835 | 12845 |
| 12836 | 12846 |
| 12837 void AllocationSite::AddDependentCompilationInfo(Reason reason, | 12847 // static |
| 12848 void AllocationSite::AddDependentCompilationInfo(Handle<AllocationSite> site, |
| 12849 Reason reason, |
| 12838 CompilationInfo* info) { | 12850 CompilationInfo* info) { |
| 12839 DependentCode::DependencyGroup group = ToDependencyGroup(reason); | 12851 DependentCode::DependencyGroup group = site->ToDependencyGroup(reason); |
| 12840 Handle<DependentCode> dep(dependent_code()); | 12852 Handle<DependentCode> dep(site->dependent_code()); |
| 12841 Handle<DependentCode> codes = | 12853 Handle<DependentCode> codes = |
| 12842 DependentCode::Insert(dep, group, info->object_wrapper()); | 12854 DependentCode::Insert(dep, group, info->object_wrapper()); |
| 12843 if (*codes != dependent_code()) set_dependent_code(*codes); | 12855 if (*codes != site->dependent_code()) site->set_dependent_code(*codes); |
| 12844 info->dependencies(group)->Add(Handle<HeapObject>(this), info->zone()); | 12856 info->dependencies(group)->Add(Handle<HeapObject>(*site), info->zone()); |
| 12845 } | 12857 } |
| 12846 | 12858 |
| 12847 | 12859 |
| 12848 void AllocationSite::AddDependentCode(Reason reason, Handle<Code> code) { | |
| 12849 DependentCode::DependencyGroup group = ToDependencyGroup(reason); | |
| 12850 Handle<DependentCode> codes = DependentCode::Insert( | |
| 12851 Handle<DependentCode>(dependent_code()), group, code); | |
| 12852 if (*codes != dependent_code()) set_dependent_code(*codes); | |
| 12853 } | |
| 12854 | |
| 12855 | |
| 12856 void JSObject::UpdateAllocationSite(Handle<JSObject> object, | 12860 void JSObject::UpdateAllocationSite(Handle<JSObject> object, |
| 12857 ElementsKind to_kind) { | 12861 ElementsKind to_kind) { |
| 12858 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), | 12862 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), |
| 12859 object->UpdateAllocationSite(to_kind)); | 12863 object->UpdateAllocationSite(to_kind)); |
| 12860 } | 12864 } |
| 12861 | 12865 |
| 12862 | 12866 |
| 12863 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { | 12867 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { |
| 12864 if (!FLAG_track_allocation_sites || !IsJSArray()) { | 12868 if (!IsJSArray()) return this; |
| 12865 return this; | |
| 12866 } | |
| 12867 | 12869 |
| 12868 if (!GetHeap()->InNewSpace(this)) return this; | 12870 Heap* heap = GetHeap(); |
| 12871 if (!heap->InNewSpace(this)) return this; |
| 12869 | 12872 |
| 12870 AllocationMemento* memento = AllocationMemento::FindForHeapObject(this); | 12873 // Either object is the last object in the new space, or there is another |
| 12871 if (memento == NULL || !memento->IsValid()) { | 12874 // object of at least word size (the header map word) following it, so |
| 12872 return this; | 12875 // suffices to compare ptr and top here. |
| 12873 } | 12876 Address ptr = address() + JSArray::kSize; |
| 12877 Address top = heap->NewSpaceTop(); |
| 12878 ASSERT(ptr == top || ptr + HeapObject::kHeaderSize <= top); |
| 12879 if (ptr == top) return this; |
| 12880 |
| 12881 HeapObject* candidate = HeapObject::FromAddress(ptr); |
| 12882 if (candidate->map() != heap->allocation_memento_map()) return this; |
| 12883 |
| 12884 AllocationMemento* memento = AllocationMemento::cast(candidate); |
| 12885 if (!memento->IsValid()) return this; |
| 12874 | 12886 |
| 12875 // Walk through to the Allocation Site | 12887 // Walk through to the Allocation Site |
| 12876 AllocationSite* site = memento->GetAllocationSite(); | 12888 AllocationSite* site = memento->GetAllocationSite(); |
| 12877 return site->DigestTransitionFeedback(to_kind); | 12889 return site->DigestTransitionFeedback(to_kind); |
| 12878 } | 12890 } |
| 12879 | 12891 |
| 12880 | 12892 |
| 12881 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { | 12893 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { |
| 12882 ElementsKind from_kind = map()->elements_kind(); | 12894 ElementsKind from_kind = map()->elements_kind(); |
| 12883 | 12895 |
| (...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13525 // purpose of this function is to provide reflection information for the object | 13537 // purpose of this function is to provide reflection information for the object |
| 13526 // mirrors. | 13538 // mirrors. |
| 13527 void JSObject::GetLocalPropertyNames( | 13539 void JSObject::GetLocalPropertyNames( |
| 13528 FixedArray* storage, int index, PropertyAttributes filter) { | 13540 FixedArray* storage, int index, PropertyAttributes filter) { |
| 13529 ASSERT(storage->length() >= (NumberOfLocalProperties(filter) - index)); | 13541 ASSERT(storage->length() >= (NumberOfLocalProperties(filter) - index)); |
| 13530 if (HasFastProperties()) { | 13542 if (HasFastProperties()) { |
| 13531 int real_size = map()->NumberOfOwnDescriptors(); | 13543 int real_size = map()->NumberOfOwnDescriptors(); |
| 13532 DescriptorArray* descs = map()->instance_descriptors(); | 13544 DescriptorArray* descs = map()->instance_descriptors(); |
| 13533 for (int i = 0; i < real_size; i++) { | 13545 for (int i = 0; i < real_size; i++) { |
| 13534 if ((descs->GetDetails(i).attributes() & filter) == 0 && | 13546 if ((descs->GetDetails(i).attributes() & filter) == 0 && |
| 13535 ((filter & SYMBOLIC) == 0 || !descs->GetKey(i)->IsSymbol())) { | 13547 !FilterKey(descs->GetKey(i), filter)) { |
| 13536 storage->set(index++, descs->GetKey(i)); | 13548 storage->set(index++, descs->GetKey(i)); |
| 13537 } | 13549 } |
| 13538 } | 13550 } |
| 13539 } else { | 13551 } else { |
| 13540 property_dictionary()->CopyKeysTo(storage, | 13552 property_dictionary()->CopyKeysTo(storage, |
| 13541 index, | 13553 index, |
| 13542 filter, | 13554 filter, |
| 13543 NameDictionary::UNSORTED); | 13555 NameDictionary::UNSORTED); |
| 13544 } | 13556 } |
| 13545 } | 13557 } |
| (...skipping 2081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15627 | 15639 |
| 15628 | 15640 |
| 15629 template<typename Shape, typename Key> | 15641 template<typename Shape, typename Key> |
| 15630 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( | 15642 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( |
| 15631 PropertyAttributes filter) { | 15643 PropertyAttributes filter) { |
| 15632 int capacity = HashTable<Shape, Key>::Capacity(); | 15644 int capacity = HashTable<Shape, Key>::Capacity(); |
| 15633 int result = 0; | 15645 int result = 0; |
| 15634 for (int i = 0; i < capacity; i++) { | 15646 for (int i = 0; i < capacity; i++) { |
| 15635 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15647 Object* k = HashTable<Shape, Key>::KeyAt(i); |
| 15636 if (HashTable<Shape, Key>::IsKey(k) && | 15648 if (HashTable<Shape, Key>::IsKey(k) && |
| 15637 ((filter & SYMBOLIC) == 0 || !k->IsSymbol())) { | 15649 !FilterKey(k, filter)) { |
| 15638 PropertyDetails details = DetailsAt(i); | 15650 PropertyDetails details = DetailsAt(i); |
| 15639 if (details.IsDeleted()) continue; | 15651 if (details.IsDeleted()) continue; |
| 15640 PropertyAttributes attr = details.attributes(); | 15652 PropertyAttributes attr = details.attributes(); |
| 15641 if ((attr & filter) == 0) result++; | 15653 if ((attr & filter) == 0) result++; |
| 15642 } | 15654 } |
| 15643 } | 15655 } |
| 15644 return result; | 15656 return result; |
| 15645 } | 15657 } |
| 15646 | 15658 |
| 15647 | 15659 |
| (...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16572 set_type_raw(type, ignored); | 16584 set_type_raw(type, ignored); |
| 16573 } | 16585 } |
| 16574 | 16586 |
| 16575 | 16587 |
| 16576 Handle<Type> PropertyCell::UpdatedType(Handle<PropertyCell> cell, | 16588 Handle<Type> PropertyCell::UpdatedType(Handle<PropertyCell> cell, |
| 16577 Handle<Object> value) { | 16589 Handle<Object> value) { |
| 16578 Isolate* isolate = cell->GetIsolate(); | 16590 Isolate* isolate = cell->GetIsolate(); |
| 16579 Handle<Type> old_type(cell->type(), isolate); | 16591 Handle<Type> old_type(cell->type(), isolate); |
| 16580 // TODO(2803): Do not track ConsString as constant because they cannot be | 16592 // TODO(2803): Do not track ConsString as constant because they cannot be |
| 16581 // embedded into code. | 16593 // embedded into code. |
| 16582 Handle<Type> new_type(value->IsConsString() || value->IsTheHole() | 16594 Handle<Type> new_type = value->IsConsString() || value->IsTheHole() |
| 16583 ? Type::Any() | 16595 ? Type::Any(isolate) : Type::Constant(value, isolate); |
| 16584 : Type::Constant(value, isolate), isolate); | |
| 16585 | 16596 |
| 16586 if (new_type->Is(old_type)) { | 16597 if (new_type->Is(old_type)) { |
| 16587 return old_type; | 16598 return old_type; |
| 16588 } | 16599 } |
| 16589 | 16600 |
| 16590 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16601 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 16591 isolate, DependentCode::kPropertyCellChangedGroup); | 16602 isolate, DependentCode::kPropertyCellChangedGroup); |
| 16592 | 16603 |
| 16593 if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) { | 16604 if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) { |
| 16594 return new_type; | 16605 return new_type; |
| 16595 } | 16606 } |
| 16596 | 16607 |
| 16597 return handle(Type::Any(), isolate); | 16608 return Type::Any(isolate); |
| 16598 } | 16609 } |
| 16599 | 16610 |
| 16600 | 16611 |
| 16601 void PropertyCell::SetValueInferType(Handle<PropertyCell> cell, | 16612 void PropertyCell::SetValueInferType(Handle<PropertyCell> cell, |
| 16602 Handle<Object> value) { | 16613 Handle<Object> value) { |
| 16603 cell->set_value(*value); | 16614 cell->set_value(*value); |
| 16604 if (!Type::Any()->Is(cell->type())) { | 16615 if (!Type::Any()->Is(cell->type())) { |
| 16605 Handle<Type> new_type = UpdatedType(cell, value); | 16616 Handle<Type> new_type = UpdatedType(cell, value); |
| 16606 cell->set_type(*new_type); | 16617 cell->set_type(*new_type); |
| 16607 } | 16618 } |
| 16608 } | 16619 } |
| 16609 | 16620 |
| 16610 | 16621 |
| 16611 void PropertyCell::AddDependentCompilationInfo(CompilationInfo* info) { | 16622 void PropertyCell::AddDependentCompilationInfo(CompilationInfo* info) { |
| 16612 Handle<DependentCode> dep(dependent_code()); | 16623 Handle<DependentCode> dep(dependent_code()); |
| 16613 Handle<DependentCode> codes = | 16624 Handle<DependentCode> codes = |
| 16614 DependentCode::Insert(dep, DependentCode::kPropertyCellChangedGroup, | 16625 DependentCode::Insert(dep, DependentCode::kPropertyCellChangedGroup, |
| 16615 info->object_wrapper()); | 16626 info->object_wrapper()); |
| 16616 if (*codes != dependent_code()) set_dependent_code(*codes); | 16627 if (*codes != dependent_code()) set_dependent_code(*codes); |
| 16617 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 16628 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 16618 Handle<HeapObject>(this), info->zone()); | 16629 Handle<HeapObject>(this), info->zone()); |
| 16619 } | 16630 } |
| 16620 | 16631 |
| 16621 | 16632 |
| 16622 void PropertyCell::AddDependentCode(Handle<Code> code) { | |
| 16623 Handle<DependentCode> codes = DependentCode::Insert( | |
| 16624 Handle<DependentCode>(dependent_code()), | |
| 16625 DependentCode::kPropertyCellChangedGroup, code); | |
| 16626 if (*codes != dependent_code()) set_dependent_code(*codes); | |
| 16627 } | |
| 16628 | |
| 16629 | |
| 16630 const char* GetBailoutReason(BailoutReason reason) { | 16633 const char* GetBailoutReason(BailoutReason reason) { |
| 16631 ASSERT(reason < kLastErrorMessage); | 16634 ASSERT(reason < kLastErrorMessage); |
| 16632 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16635 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16633 static const char* error_messages_[] = { | 16636 static const char* error_messages_[] = { |
| 16634 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16637 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16635 }; | 16638 }; |
| 16636 #undef ERROR_MESSAGES_TEXTS | 16639 #undef ERROR_MESSAGES_TEXTS |
| 16637 return error_messages_[reason]; | 16640 return error_messages_[reason]; |
| 16638 } | 16641 } |
| 16639 | 16642 |
| 16640 | 16643 |
| 16641 } } // namespace v8::internal | 16644 } } // namespace v8::internal |
| OLD | NEW |