| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 guard_ = false; | 1068 guard_ = false; |
| 1069 } | 1069 } |
| 1070 | 1070 |
| 1071 | 1071 |
| 1072 void PromotionQueue::RelocateQueueHead() { | 1072 void PromotionQueue::RelocateQueueHead() { |
| 1073 ASSERT(emergency_stack_ == NULL); | 1073 ASSERT(emergency_stack_ == NULL); |
| 1074 | 1074 |
| 1075 Page* p = Page::FromAllocationTop(reinterpret_cast<Address>(rear_)); | 1075 Page* p = Page::FromAllocationTop(reinterpret_cast<Address>(rear_)); |
| 1076 intptr_t* head_start = rear_; | 1076 intptr_t* head_start = rear_; |
| 1077 intptr_t* head_end = | 1077 intptr_t* head_end = |
| 1078 Min(front_, reinterpret_cast<intptr_t*>(p->body_limit())); | 1078 Min(front_, reinterpret_cast<intptr_t*>(p->area_end())); |
| 1079 | 1079 |
| 1080 int entries_count = | 1080 int entries_count = |
| 1081 static_cast<int>(head_end - head_start) / kEntrySizeInWords; | 1081 static_cast<int>(head_end - head_start) / kEntrySizeInWords; |
| 1082 | 1082 |
| 1083 emergency_stack_ = new List<Entry>(2 * entries_count); | 1083 emergency_stack_ = new List<Entry>(2 * entries_count); |
| 1084 | 1084 |
| 1085 while (head_start != head_end) { | 1085 while (head_start != head_end) { |
| 1086 int size = static_cast<int>(*(head_start++)); | 1086 int size = static_cast<int>(*(head_start++)); |
| 1087 HeapObject* obj = reinterpret_cast<HeapObject*>(*(head_start++)); | 1087 HeapObject* obj = reinterpret_cast<HeapObject*>(*(head_start++)); |
| 1088 emergency_stack_->Add(Entry(obj, size)); | 1088 emergency_stack_->Add(Entry(obj, size)); |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1409 // The addresses new_space_front and new_space_.top() define a | 1409 // The addresses new_space_front and new_space_.top() define a |
| 1410 // queue of unprocessed copied objects. Process them until the | 1410 // queue of unprocessed copied objects. Process them until the |
| 1411 // queue is empty. | 1411 // queue is empty. |
| 1412 while (new_space_front != new_space_.top()) { | 1412 while (new_space_front != new_space_.top()) { |
| 1413 if (!NewSpacePage::IsAtEnd(new_space_front)) { | 1413 if (!NewSpacePage::IsAtEnd(new_space_front)) { |
| 1414 HeapObject* object = HeapObject::FromAddress(new_space_front); | 1414 HeapObject* object = HeapObject::FromAddress(new_space_front); |
| 1415 new_space_front += | 1415 new_space_front += |
| 1416 NewSpaceScavenger::IterateBody(object->map(), object); | 1416 NewSpaceScavenger::IterateBody(object->map(), object); |
| 1417 } else { | 1417 } else { |
| 1418 new_space_front = | 1418 new_space_front = |
| 1419 NewSpacePage::FromLimit(new_space_front)->next_page()->body(); | 1419 NewSpacePage::FromLimit(new_space_front)->next_page()->area_start(); |
| 1420 } | 1420 } |
| 1421 } | 1421 } |
| 1422 | 1422 |
| 1423 // Promote and process all the to-be-promoted objects. | 1423 // Promote and process all the to-be-promoted objects. |
| 1424 { | 1424 { |
| 1425 StoreBufferRebuildScope scope(this, | 1425 StoreBufferRebuildScope scope(this, |
| 1426 store_buffer(), | 1426 store_buffer(), |
| 1427 &ScavengeStoreBufferCallback); | 1427 &ScavengeStoreBufferCallback); |
| 1428 while (!promotion_queue()->is_empty()) { | 1428 while (!promotion_queue()->is_empty()) { |
| 1429 HeapObject* target; | 1429 HeapObject* target; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1571 } | 1571 } |
| 1572 } | 1572 } |
| 1573 } | 1573 } |
| 1574 | 1574 |
| 1575 template<ObjectContents object_contents, SizeRestriction size_restriction> | 1575 template<ObjectContents object_contents, SizeRestriction size_restriction> |
| 1576 static inline void EvacuateObject(Map* map, | 1576 static inline void EvacuateObject(Map* map, |
| 1577 HeapObject** slot, | 1577 HeapObject** slot, |
| 1578 HeapObject* object, | 1578 HeapObject* object, |
| 1579 int object_size) { | 1579 int object_size) { |
| 1580 SLOW_ASSERT((size_restriction != SMALL) || | 1580 SLOW_ASSERT((size_restriction != SMALL) || |
| 1581 (object_size <= Page::kMaxHeapObjectSize)); | 1581 (object_size <= Page::kMaxNonCodeHeapObjectSize)); |
| 1582 SLOW_ASSERT(object->Size() == object_size); | 1582 SLOW_ASSERT(object->Size() == object_size); |
| 1583 | 1583 |
| 1584 Heap* heap = map->GetHeap(); | 1584 Heap* heap = map->GetHeap(); |
| 1585 if (heap->ShouldBePromoted(object->address(), object_size)) { | 1585 if (heap->ShouldBePromoted(object->address(), object_size)) { |
| 1586 MaybeObject* maybe_result; | 1586 MaybeObject* maybe_result; |
| 1587 | 1587 |
| 1588 if ((size_restriction != SMALL) && | 1588 if ((size_restriction != SMALL) && |
| 1589 (object_size > Page::kMaxHeapObjectSize)) { | 1589 (object_size > Page::kMaxNonCodeHeapObjectSize)) { |
| 1590 maybe_result = heap->lo_space()->AllocateRaw(object_size, | 1590 maybe_result = heap->lo_space()->AllocateRaw(object_size, |
| 1591 NOT_EXECUTABLE); | 1591 NOT_EXECUTABLE); |
| 1592 } else { | 1592 } else { |
| 1593 if (object_contents == DATA_OBJECT) { | 1593 if (object_contents == DATA_OBJECT) { |
| 1594 maybe_result = heap->old_data_space()->AllocateRaw(object_size); | 1594 maybe_result = heap->old_data_space()->AllocateRaw(object_size); |
| 1595 } else { | 1595 } else { |
| 1596 maybe_result = heap->old_pointer_space()->AllocateRaw(object_size); | 1596 maybe_result = heap->old_pointer_space()->AllocateRaw(object_size); |
| 1597 } | 1597 } |
| 1598 } | 1598 } |
| 1599 | 1599 |
| (...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2219 set_message_object_map(Map::cast(obj)); | 2219 set_message_object_map(Map::cast(obj)); |
| 2220 | 2220 |
| 2221 ASSERT(!InNewSpace(empty_fixed_array())); | 2221 ASSERT(!InNewSpace(empty_fixed_array())); |
| 2222 return true; | 2222 return true; |
| 2223 } | 2223 } |
| 2224 | 2224 |
| 2225 | 2225 |
| 2226 MaybeObject* Heap::AllocateHeapNumber(double value, PretenureFlag pretenure) { | 2226 MaybeObject* Heap::AllocateHeapNumber(double value, PretenureFlag pretenure) { |
| 2227 // Statically ensure that it is safe to allocate heap numbers in paged | 2227 // Statically ensure that it is safe to allocate heap numbers in paged |
| 2228 // spaces. | 2228 // spaces. |
| 2229 STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxHeapObjectSize); | 2229 STATIC_ASSERT(HeapNumber::kSize <= Page::kNonCodeObjectAreaSize); |
| 2230 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; | 2230 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
| 2231 | 2231 |
| 2232 Object* result; | 2232 Object* result; |
| 2233 { MaybeObject* maybe_result = | 2233 { MaybeObject* maybe_result = |
| 2234 AllocateRaw(HeapNumber::kSize, space, OLD_DATA_SPACE); | 2234 AllocateRaw(HeapNumber::kSize, space, OLD_DATA_SPACE); |
| 2235 if (!maybe_result->ToObject(&result)) return maybe_result; | 2235 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2236 } | 2236 } |
| 2237 | 2237 |
| 2238 HeapObject::cast(result)->set_map_no_write_barrier(heap_number_map()); | 2238 HeapObject::cast(result)->set_map_no_write_barrier(heap_number_map()); |
| 2239 HeapNumber::cast(result)->set_value(value); | 2239 HeapNumber::cast(result)->set_value(value); |
| 2240 return result; | 2240 return result; |
| 2241 } | 2241 } |
| 2242 | 2242 |
| 2243 | 2243 |
| 2244 MaybeObject* Heap::AllocateHeapNumber(double value) { | 2244 MaybeObject* Heap::AllocateHeapNumber(double value) { |
| 2245 // Use general version, if we're forced to always allocate. | 2245 // Use general version, if we're forced to always allocate. |
| 2246 if (always_allocate()) return AllocateHeapNumber(value, TENURED); | 2246 if (always_allocate()) return AllocateHeapNumber(value, TENURED); |
| 2247 | 2247 |
| 2248 // This version of AllocateHeapNumber is optimized for | 2248 // This version of AllocateHeapNumber is optimized for |
| 2249 // allocation in new space. | 2249 // allocation in new space. |
| 2250 STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxHeapObjectSize); | 2250 STATIC_ASSERT(HeapNumber::kSize <= Page::kMaxNonCodeHeapObjectSize); |
| 2251 ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); | 2251 ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); |
| 2252 Object* result; | 2252 Object* result; |
| 2253 { MaybeObject* maybe_result = new_space_.AllocateRaw(HeapNumber::kSize); | 2253 { MaybeObject* maybe_result = new_space_.AllocateRaw(HeapNumber::kSize); |
| 2254 if (!maybe_result->ToObject(&result)) return maybe_result; | 2254 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2255 } | 2255 } |
| 2256 HeapObject::cast(result)->set_map_no_write_barrier(heap_number_map()); | 2256 HeapObject::cast(result)->set_map_no_write_barrier(heap_number_map()); |
| 2257 HeapNumber::cast(result)->set_value(value); | 2257 HeapNumber::cast(result)->set_value(value); |
| 2258 return result; | 2258 return result; |
| 2259 } | 2259 } |
| 2260 | 2260 |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2778 return Smi::FromInt(int_value); | 2778 return Smi::FromInt(int_value); |
| 2779 } | 2779 } |
| 2780 | 2780 |
| 2781 // Materialize the value in the heap. | 2781 // Materialize the value in the heap. |
| 2782 return AllocateHeapNumber(value, pretenure); | 2782 return AllocateHeapNumber(value, pretenure); |
| 2783 } | 2783 } |
| 2784 | 2784 |
| 2785 | 2785 |
| 2786 MaybeObject* Heap::AllocateForeign(Address address, PretenureFlag pretenure) { | 2786 MaybeObject* Heap::AllocateForeign(Address address, PretenureFlag pretenure) { |
| 2787 // Statically ensure that it is safe to allocate foreigns in paged spaces. | 2787 // Statically ensure that it is safe to allocate foreigns in paged spaces. |
| 2788 STATIC_ASSERT(Foreign::kSize <= Page::kMaxHeapObjectSize); | 2788 STATIC_ASSERT(Foreign::kSize <= Page::kMaxNonCodeHeapObjectSize); |
| 2789 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; | 2789 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
| 2790 Foreign* result; | 2790 Foreign* result; |
| 2791 MaybeObject* maybe_result = Allocate(foreign_map(), space); | 2791 MaybeObject* maybe_result = Allocate(foreign_map(), space); |
| 2792 if (!maybe_result->To(&result)) return maybe_result; | 2792 if (!maybe_result->To(&result)) return maybe_result; |
| 2793 result->set_foreign_address(address); | 2793 result->set_foreign_address(address); |
| 2794 return result; | 2794 return result; |
| 2795 } | 2795 } |
| 2796 | 2796 |
| 2797 | 2797 |
| 2798 MaybeObject* Heap::AllocateSharedFunctionInfo(Object* name) { | 2798 MaybeObject* Heap::AllocateSharedFunctionInfo(Object* name) { |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3194 | 3194 |
| 3195 MaybeObject* Heap::AllocateByteArray(int length, PretenureFlag pretenure) { | 3195 MaybeObject* Heap::AllocateByteArray(int length, PretenureFlag pretenure) { |
| 3196 if (length < 0 || length > ByteArray::kMaxLength) { | 3196 if (length < 0 || length > ByteArray::kMaxLength) { |
| 3197 return Failure::OutOfMemoryException(); | 3197 return Failure::OutOfMemoryException(); |
| 3198 } | 3198 } |
| 3199 if (pretenure == NOT_TENURED) { | 3199 if (pretenure == NOT_TENURED) { |
| 3200 return AllocateByteArray(length); | 3200 return AllocateByteArray(length); |
| 3201 } | 3201 } |
| 3202 int size = ByteArray::SizeFor(length); | 3202 int size = ByteArray::SizeFor(length); |
| 3203 Object* result; | 3203 Object* result; |
| 3204 { MaybeObject* maybe_result = (size <= MaxObjectSizeInPagedSpace()) | 3204 { MaybeObject* maybe_result = (size <= Page::kMaxNonCodeHeapObjectSize) |
| 3205 ? old_data_space_->AllocateRaw(size) | 3205 ? old_data_space_->AllocateRaw(size) |
| 3206 : lo_space_->AllocateRaw(size, NOT_EXECUTABLE); | 3206 : lo_space_->AllocateRaw(size, NOT_EXECUTABLE); |
| 3207 if (!maybe_result->ToObject(&result)) return maybe_result; | 3207 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3208 } | 3208 } |
| 3209 | 3209 |
| 3210 reinterpret_cast<ByteArray*>(result)->set_map_no_write_barrier( | 3210 reinterpret_cast<ByteArray*>(result)->set_map_no_write_barrier( |
| 3211 byte_array_map()); | 3211 byte_array_map()); |
| 3212 reinterpret_cast<ByteArray*>(result)->set_length(length); | 3212 reinterpret_cast<ByteArray*>(result)->set_length(length); |
| 3213 return result; | 3213 return result; |
| 3214 } | 3214 } |
| 3215 | 3215 |
| 3216 | 3216 |
| 3217 MaybeObject* Heap::AllocateByteArray(int length) { | 3217 MaybeObject* Heap::AllocateByteArray(int length) { |
| 3218 if (length < 0 || length > ByteArray::kMaxLength) { | 3218 if (length < 0 || length > ByteArray::kMaxLength) { |
| 3219 return Failure::OutOfMemoryException(); | 3219 return Failure::OutOfMemoryException(); |
| 3220 } | 3220 } |
| 3221 int size = ByteArray::SizeFor(length); | 3221 int size = ByteArray::SizeFor(length); |
| 3222 AllocationSpace space = | 3222 AllocationSpace space = |
| 3223 (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : NEW_SPACE; | 3223 (size > Page::kMaxNonCodeHeapObjectSize) ? LO_SPACE : NEW_SPACE; |
| 3224 Object* result; | 3224 Object* result; |
| 3225 { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE); | 3225 { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE); |
| 3226 if (!maybe_result->ToObject(&result)) return maybe_result; | 3226 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3227 } | 3227 } |
| 3228 | 3228 |
| 3229 reinterpret_cast<ByteArray*>(result)->set_map_no_write_barrier( | 3229 reinterpret_cast<ByteArray*>(result)->set_map_no_write_barrier( |
| 3230 byte_array_map()); | 3230 byte_array_map()); |
| 3231 reinterpret_cast<ByteArray*>(result)->set_length(length); | 3231 reinterpret_cast<ByteArray*>(result)->set_length(length); |
| 3232 return result; | 3232 return result; |
| 3233 } | 3233 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3279 MaybeObject* maybe_reloc_info = AllocateByteArray(desc.reloc_size, TENURED); | 3279 MaybeObject* maybe_reloc_info = AllocateByteArray(desc.reloc_size, TENURED); |
| 3280 if (!maybe_reloc_info->To(&reloc_info)) return maybe_reloc_info; | 3280 if (!maybe_reloc_info->To(&reloc_info)) return maybe_reloc_info; |
| 3281 | 3281 |
| 3282 // Compute size. | 3282 // Compute size. |
| 3283 int body_size = RoundUp(desc.instr_size, kObjectAlignment); | 3283 int body_size = RoundUp(desc.instr_size, kObjectAlignment); |
| 3284 int obj_size = Code::SizeFor(body_size); | 3284 int obj_size = Code::SizeFor(body_size); |
| 3285 ASSERT(IsAligned(static_cast<intptr_t>(obj_size), kCodeAlignment)); | 3285 ASSERT(IsAligned(static_cast<intptr_t>(obj_size), kCodeAlignment)); |
| 3286 MaybeObject* maybe_result; | 3286 MaybeObject* maybe_result; |
| 3287 // Large code objects and code objects which should stay at a fixed address | 3287 // Large code objects and code objects which should stay at a fixed address |
| 3288 // are allocated in large object space. | 3288 // are allocated in large object space. |
| 3289 if (obj_size > MaxObjectSizeInPagedSpace() || immovable) { | 3289 if (obj_size > code_space()->AreaSize() || immovable) { |
| 3290 maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE); | 3290 maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE); |
| 3291 } else { | 3291 } else { |
| 3292 maybe_result = code_space_->AllocateRaw(obj_size); | 3292 maybe_result = code_space_->AllocateRaw(obj_size); |
| 3293 } | 3293 } |
| 3294 | 3294 |
| 3295 Object* result; | 3295 Object* result; |
| 3296 if (!maybe_result->ToObject(&result)) return maybe_result; | 3296 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3297 | 3297 |
| 3298 // Initialize the object | 3298 // Initialize the object |
| 3299 HeapObject::cast(result)->set_map_no_write_barrier(code_map()); | 3299 HeapObject::cast(result)->set_map_no_write_barrier(code_map()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3327 } | 3327 } |
| 3328 #endif | 3328 #endif |
| 3329 return code; | 3329 return code; |
| 3330 } | 3330 } |
| 3331 | 3331 |
| 3332 | 3332 |
| 3333 MaybeObject* Heap::CopyCode(Code* code) { | 3333 MaybeObject* Heap::CopyCode(Code* code) { |
| 3334 // Allocate an object the same size as the code object. | 3334 // Allocate an object the same size as the code object. |
| 3335 int obj_size = code->Size(); | 3335 int obj_size = code->Size(); |
| 3336 MaybeObject* maybe_result; | 3336 MaybeObject* maybe_result; |
| 3337 if (obj_size > MaxObjectSizeInPagedSpace()) { | 3337 if (obj_size > code_space()->AreaSize()) { |
| 3338 maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE); | 3338 maybe_result = lo_space_->AllocateRaw(obj_size, EXECUTABLE); |
| 3339 } else { | 3339 } else { |
| 3340 maybe_result = code_space_->AllocateRaw(obj_size); | 3340 maybe_result = code_space_->AllocateRaw(obj_size); |
| 3341 } | 3341 } |
| 3342 | 3342 |
| 3343 Object* result; | 3343 Object* result; |
| 3344 if (!maybe_result->ToObject(&result)) return maybe_result; | 3344 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3345 | 3345 |
| 3346 // Copy code object. | 3346 // Copy code object. |
| 3347 Address old_addr = code->address(); | 3347 Address old_addr = code->address(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3370 int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment); | 3370 int new_body_size = RoundUp(code->instruction_size(), kObjectAlignment); |
| 3371 | 3371 |
| 3372 int new_obj_size = Code::SizeFor(new_body_size); | 3372 int new_obj_size = Code::SizeFor(new_body_size); |
| 3373 | 3373 |
| 3374 Address old_addr = code->address(); | 3374 Address old_addr = code->address(); |
| 3375 | 3375 |
| 3376 size_t relocation_offset = | 3376 size_t relocation_offset = |
| 3377 static_cast<size_t>(code->instruction_end() - old_addr); | 3377 static_cast<size_t>(code->instruction_end() - old_addr); |
| 3378 | 3378 |
| 3379 MaybeObject* maybe_result; | 3379 MaybeObject* maybe_result; |
| 3380 if (new_obj_size > MaxObjectSizeInPagedSpace()) { | 3380 if (new_obj_size > code_space()->AreaSize()) { |
| 3381 maybe_result = lo_space_->AllocateRaw(new_obj_size, EXECUTABLE); | 3381 maybe_result = lo_space_->AllocateRaw(new_obj_size, EXECUTABLE); |
| 3382 } else { | 3382 } else { |
| 3383 maybe_result = code_space_->AllocateRaw(new_obj_size); | 3383 maybe_result = code_space_->AllocateRaw(new_obj_size); |
| 3384 } | 3384 } |
| 3385 | 3385 |
| 3386 Object* result; | 3386 Object* result; |
| 3387 if (!maybe_result->ToObject(&result)) return maybe_result; | 3387 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3388 | 3388 |
| 3389 // Copy code object. | 3389 // Copy code object. |
| 3390 Address new_addr = reinterpret_cast<HeapObject*>(result)->address(); | 3390 Address new_addr = reinterpret_cast<HeapObject*>(result)->address(); |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3691 map->inobject_properties(); | 3691 map->inobject_properties(); |
| 3692 ASSERT(prop_size >= 0); | 3692 ASSERT(prop_size >= 0); |
| 3693 Object* properties; | 3693 Object* properties; |
| 3694 { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, pretenure); | 3694 { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, pretenure); |
| 3695 if (!maybe_properties->ToObject(&properties)) return maybe_properties; | 3695 if (!maybe_properties->ToObject(&properties)) return maybe_properties; |
| 3696 } | 3696 } |
| 3697 | 3697 |
| 3698 // Allocate the JSObject. | 3698 // Allocate the JSObject. |
| 3699 AllocationSpace space = | 3699 AllocationSpace space = |
| 3700 (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; | 3700 (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; |
| 3701 if (map->instance_size() > MaxObjectSizeInPagedSpace()) space = LO_SPACE; | 3701 if (map->instance_size() > Page::kMaxNonCodeHeapObjectSize) space = LO_SPACE; |
| 3702 Object* obj; | 3702 Object* obj; |
| 3703 { MaybeObject* maybe_obj = Allocate(map, space); | 3703 { MaybeObject* maybe_obj = Allocate(map, space); |
| 3704 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 3704 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 3705 } | 3705 } |
| 3706 | 3706 |
| 3707 // Initialize the JSObject. | 3707 // Initialize the JSObject. |
| 3708 InitializeJSObjectFromMap(JSObject::cast(obj), | 3708 InitializeJSObjectFromMap(JSObject::cast(obj), |
| 3709 FixedArray::cast(properties), | 3709 FixedArray::cast(properties), |
| 3710 map); | 3710 map); |
| 3711 ASSERT(JSObject::cast(obj)->HasFastSmiOnlyElements() || | 3711 ASSERT(JSObject::cast(obj)->HasFastSmiOnlyElements() || |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4141 } else { | 4141 } else { |
| 4142 if (chars > SeqTwoByteString::kMaxLength) { | 4142 if (chars > SeqTwoByteString::kMaxLength) { |
| 4143 return Failure::OutOfMemoryException(); | 4143 return Failure::OutOfMemoryException(); |
| 4144 } | 4144 } |
| 4145 map = symbol_map(); | 4145 map = symbol_map(); |
| 4146 size = SeqTwoByteString::SizeFor(chars); | 4146 size = SeqTwoByteString::SizeFor(chars); |
| 4147 } | 4147 } |
| 4148 | 4148 |
| 4149 // Allocate string. | 4149 // Allocate string. |
| 4150 Object* result; | 4150 Object* result; |
| 4151 { MaybeObject* maybe_result = (size > MaxObjectSizeInPagedSpace()) | 4151 { MaybeObject* maybe_result = (size > Page::kMaxNonCodeHeapObjectSize) |
| 4152 ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE) | 4152 ? lo_space_->AllocateRaw(size, NOT_EXECUTABLE) |
| 4153 : old_data_space_->AllocateRaw(size); | 4153 : old_data_space_->AllocateRaw(size); |
| 4154 if (!maybe_result->ToObject(&result)) return maybe_result; | 4154 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 4155 } | 4155 } |
| 4156 | 4156 |
| 4157 reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier(map); | 4157 reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier(map); |
| 4158 // Set length and hash fields of the allocated string. | 4158 // Set length and hash fields of the allocated string. |
| 4159 String* answer = String::cast(result); | 4159 String* answer = String::cast(result); |
| 4160 answer->set_length(chars); | 4160 answer->set_length(chars); |
| 4161 answer->set_hash_field(hash_field); | 4161 answer->set_hash_field(hash_field); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4178 int size = SeqAsciiString::SizeFor(length); | 4178 int size = SeqAsciiString::SizeFor(length); |
| 4179 ASSERT(size <= SeqAsciiString::kMaxSize); | 4179 ASSERT(size <= SeqAsciiString::kMaxSize); |
| 4180 | 4180 |
| 4181 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; | 4181 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
| 4182 AllocationSpace retry_space = OLD_DATA_SPACE; | 4182 AllocationSpace retry_space = OLD_DATA_SPACE; |
| 4183 | 4183 |
| 4184 if (space == NEW_SPACE) { | 4184 if (space == NEW_SPACE) { |
| 4185 if (size > kMaxObjectSizeInNewSpace) { | 4185 if (size > kMaxObjectSizeInNewSpace) { |
| 4186 // Allocate in large object space, retry space will be ignored. | 4186 // Allocate in large object space, retry space will be ignored. |
| 4187 space = LO_SPACE; | 4187 space = LO_SPACE; |
| 4188 } else if (size > MaxObjectSizeInPagedSpace()) { | 4188 } else if (size > Page::kMaxNonCodeHeapObjectSize) { |
| 4189 // Allocate in new space, retry in large object space. | 4189 // Allocate in new space, retry in large object space. |
| 4190 retry_space = LO_SPACE; | 4190 retry_space = LO_SPACE; |
| 4191 } | 4191 } |
| 4192 } else if (space == OLD_DATA_SPACE && size > MaxObjectSizeInPagedSpace()) { | 4192 } else if (space == OLD_DATA_SPACE && |
| 4193 size > Page::kMaxNonCodeHeapObjectSize) { |
| 4193 space = LO_SPACE; | 4194 space = LO_SPACE; |
| 4194 } | 4195 } |
| 4195 Object* result; | 4196 Object* result; |
| 4196 { MaybeObject* maybe_result = AllocateRaw(size, space, retry_space); | 4197 { MaybeObject* maybe_result = AllocateRaw(size, space, retry_space); |
| 4197 if (!maybe_result->ToObject(&result)) return maybe_result; | 4198 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 4198 } | 4199 } |
| 4199 | 4200 |
| 4200 // Partially initialize the object. | 4201 // Partially initialize the object. |
| 4201 HeapObject::cast(result)->set_map_no_write_barrier(ascii_string_map()); | 4202 HeapObject::cast(result)->set_map_no_write_barrier(ascii_string_map()); |
| 4202 String::cast(result)->set_length(length); | 4203 String::cast(result)->set_length(length); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4213 } | 4214 } |
| 4214 int size = SeqTwoByteString::SizeFor(length); | 4215 int size = SeqTwoByteString::SizeFor(length); |
| 4215 ASSERT(size <= SeqTwoByteString::kMaxSize); | 4216 ASSERT(size <= SeqTwoByteString::kMaxSize); |
| 4216 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; | 4217 AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
| 4217 AllocationSpace retry_space = OLD_DATA_SPACE; | 4218 AllocationSpace retry_space = OLD_DATA_SPACE; |
| 4218 | 4219 |
| 4219 if (space == NEW_SPACE) { | 4220 if (space == NEW_SPACE) { |
| 4220 if (size > kMaxObjectSizeInNewSpace) { | 4221 if (size > kMaxObjectSizeInNewSpace) { |
| 4221 // Allocate in large object space, retry space will be ignored. | 4222 // Allocate in large object space, retry space will be ignored. |
| 4222 space = LO_SPACE; | 4223 space = LO_SPACE; |
| 4223 } else if (size > MaxObjectSizeInPagedSpace()) { | 4224 } else if (size > Page::kMaxNonCodeHeapObjectSize) { |
| 4224 // Allocate in new space, retry in large object space. | 4225 // Allocate in new space, retry in large object space. |
| 4225 retry_space = LO_SPACE; | 4226 retry_space = LO_SPACE; |
| 4226 } | 4227 } |
| 4227 } else if (space == OLD_DATA_SPACE && size > MaxObjectSizeInPagedSpace()) { | 4228 } else if (space == OLD_DATA_SPACE && |
| 4229 size > Page::kMaxNonCodeHeapObjectSize) { |
| 4228 space = LO_SPACE; | 4230 space = LO_SPACE; |
| 4229 } | 4231 } |
| 4230 Object* result; | 4232 Object* result; |
| 4231 { MaybeObject* maybe_result = AllocateRaw(size, space, retry_space); | 4233 { MaybeObject* maybe_result = AllocateRaw(size, space, retry_space); |
| 4232 if (!maybe_result->ToObject(&result)) return maybe_result; | 4234 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 4233 } | 4235 } |
| 4234 | 4236 |
| 4235 // Partially initialize the object. | 4237 // Partially initialize the object. |
| 4236 HeapObject::cast(result)->set_map_no_write_barrier(string_map()); | 4238 HeapObject::cast(result)->set_map_no_write_barrier(string_map()); |
| 4237 String::cast(result)->set_length(length); | 4239 String::cast(result)->set_length(length); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4337 return Failure::OutOfMemoryException(); | 4339 return Failure::OutOfMemoryException(); |
| 4338 } | 4340 } |
| 4339 | 4341 |
| 4340 AllocationSpace space = | 4342 AllocationSpace space = |
| 4341 (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; | 4343 (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; |
| 4342 int size = FixedArray::SizeFor(length); | 4344 int size = FixedArray::SizeFor(length); |
| 4343 if (space == NEW_SPACE && size > kMaxObjectSizeInNewSpace) { | 4345 if (space == NEW_SPACE && size > kMaxObjectSizeInNewSpace) { |
| 4344 // Too big for new space. | 4346 // Too big for new space. |
| 4345 space = LO_SPACE; | 4347 space = LO_SPACE; |
| 4346 } else if (space == OLD_POINTER_SPACE && | 4348 } else if (space == OLD_POINTER_SPACE && |
| 4347 size > MaxObjectSizeInPagedSpace()) { | 4349 size > Page::kMaxNonCodeHeapObjectSize) { |
| 4348 // Too big for old pointer space. | 4350 // Too big for old pointer space. |
| 4349 space = LO_SPACE; | 4351 space = LO_SPACE; |
| 4350 } | 4352 } |
| 4351 | 4353 |
| 4352 AllocationSpace retry_space = | 4354 AllocationSpace retry_space = |
| 4353 (size <= MaxObjectSizeInPagedSpace()) ? OLD_POINTER_SPACE : LO_SPACE; | 4355 (size <= Page::kMaxNonCodeHeapObjectSize) ? OLD_POINTER_SPACE : LO_SPACE; |
| 4354 | 4356 |
| 4355 return AllocateRaw(size, space, retry_space); | 4357 return AllocateRaw(size, space, retry_space); |
| 4356 } | 4358 } |
| 4357 | 4359 |
| 4358 | 4360 |
| 4359 MUST_USE_RESULT static MaybeObject* AllocateFixedArrayWithFiller( | 4361 MUST_USE_RESULT static MaybeObject* AllocateFixedArrayWithFiller( |
| 4360 Heap* heap, | 4362 Heap* heap, |
| 4361 int length, | 4363 int length, |
| 4362 PretenureFlag pretenure, | 4364 PretenureFlag pretenure, |
| 4363 Object* filler) { | 4365 Object* filler) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4449 return Failure::OutOfMemoryException(); | 4451 return Failure::OutOfMemoryException(); |
| 4450 } | 4452 } |
| 4451 | 4453 |
| 4452 AllocationSpace space = | 4454 AllocationSpace space = |
| 4453 (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; | 4455 (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
| 4454 int size = FixedDoubleArray::SizeFor(length); | 4456 int size = FixedDoubleArray::SizeFor(length); |
| 4455 if (space == NEW_SPACE && size > kMaxObjectSizeInNewSpace) { | 4457 if (space == NEW_SPACE && size > kMaxObjectSizeInNewSpace) { |
| 4456 // Too big for new space. | 4458 // Too big for new space. |
| 4457 space = LO_SPACE; | 4459 space = LO_SPACE; |
| 4458 } else if (space == OLD_DATA_SPACE && | 4460 } else if (space == OLD_DATA_SPACE && |
| 4459 size > MaxObjectSizeInPagedSpace()) { | 4461 size > Page::kMaxNonCodeHeapObjectSize) { |
| 4460 // Too big for old data space. | 4462 // Too big for old data space. |
| 4461 space = LO_SPACE; | 4463 space = LO_SPACE; |
| 4462 } | 4464 } |
| 4463 | 4465 |
| 4464 AllocationSpace retry_space = | 4466 AllocationSpace retry_space = |
| 4465 (size <= MaxObjectSizeInPagedSpace()) ? OLD_DATA_SPACE : LO_SPACE; | 4467 (size <= Page::kMaxNonCodeHeapObjectSize) ? OLD_DATA_SPACE : LO_SPACE; |
| 4466 | 4468 |
| 4467 return AllocateRaw(size, space, retry_space); | 4469 return AllocateRaw(size, space, retry_space); |
| 4468 } | 4470 } |
| 4469 | 4471 |
| 4470 | 4472 |
| 4471 MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) { | 4473 MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) { |
| 4472 Object* result; | 4474 Object* result; |
| 4473 { MaybeObject* maybe_result = AllocateFixedArray(length, pretenure); | 4475 { MaybeObject* maybe_result = AllocateFixedArray(length, pretenure); |
| 4474 if (!maybe_result->ToObject(&result)) return maybe_result; | 4476 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 4475 } | 4477 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4581 #define MAKE_CASE(NAME, Name, name) \ | 4583 #define MAKE_CASE(NAME, Name, name) \ |
| 4582 case NAME##_TYPE: map = name##_map(); break; | 4584 case NAME##_TYPE: map = name##_map(); break; |
| 4583 STRUCT_LIST(MAKE_CASE) | 4585 STRUCT_LIST(MAKE_CASE) |
| 4584 #undef MAKE_CASE | 4586 #undef MAKE_CASE |
| 4585 default: | 4587 default: |
| 4586 UNREACHABLE(); | 4588 UNREACHABLE(); |
| 4587 return Failure::InternalError(); | 4589 return Failure::InternalError(); |
| 4588 } | 4590 } |
| 4589 int size = map->instance_size(); | 4591 int size = map->instance_size(); |
| 4590 AllocationSpace space = | 4592 AllocationSpace space = |
| 4591 (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : OLD_POINTER_SPACE; | 4593 (size > Page::kMaxNonCodeHeapObjectSize) ? LO_SPACE : OLD_POINTER_SPACE; |
| 4592 Object* result; | 4594 Object* result; |
| 4593 { MaybeObject* maybe_result = Allocate(map, space); | 4595 { MaybeObject* maybe_result = Allocate(map, space); |
| 4594 if (!maybe_result->ToObject(&result)) return maybe_result; | 4596 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 4595 } | 4597 } |
| 4596 Struct::cast(result)->InitializeBody(size); | 4598 Struct::cast(result)->InitializeBody(size); |
| 4597 return result; | 4599 return result; |
| 4598 } | 4600 } |
| 4599 | 4601 |
| 4600 | 4602 |
| 4601 bool Heap::IsHeapIterable() { | 4603 bool Heap::IsHeapIterable() { |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4997 return symbol_table()->LookupSymbolIfExists(string, symbol); | 4999 return symbol_table()->LookupSymbolIfExists(string, symbol); |
| 4998 } | 5000 } |
| 4999 | 5001 |
| 5000 | 5002 |
| 5001 #ifdef DEBUG | 5003 #ifdef DEBUG |
| 5002 void Heap::ZapFromSpace() { | 5004 void Heap::ZapFromSpace() { |
| 5003 NewSpacePageIterator it(new_space_.FromSpaceStart(), | 5005 NewSpacePageIterator it(new_space_.FromSpaceStart(), |
| 5004 new_space_.FromSpaceEnd()); | 5006 new_space_.FromSpaceEnd()); |
| 5005 while (it.has_next()) { | 5007 while (it.has_next()) { |
| 5006 NewSpacePage* page = it.next(); | 5008 NewSpacePage* page = it.next(); |
| 5007 for (Address cursor = page->body(), limit = page->body_limit(); | 5009 for (Address cursor = page->area_start(), limit = page->area_end(); |
| 5008 cursor < limit; | 5010 cursor < limit; |
| 5009 cursor += kPointerSize) { | 5011 cursor += kPointerSize) { |
| 5010 Memory::Address_at(cursor) = kFromSpaceZapValue; | 5012 Memory::Address_at(cursor) = kFromSpaceZapValue; |
| 5011 } | 5013 } |
| 5012 } | 5014 } |
| 5013 } | 5015 } |
| 5014 #endif // DEBUG | 5016 #endif // DEBUG |
| 5015 | 5017 |
| 5016 | 5018 |
| 5017 void Heap::IterateAndMarkPointersToFromSpace(Address start, | 5019 void Heap::IterateAndMarkPointersToFromSpace(Address start, |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5136 // scanning a page and ensuring that all pointers to young space are in the | 5138 // scanning a page and ensuring that all pointers to young space are in the |
| 5137 // store buffer. | 5139 // store buffer. |
| 5138 void Heap::OldPointerSpaceCheckStoreBuffer() { | 5140 void Heap::OldPointerSpaceCheckStoreBuffer() { |
| 5139 OldSpace* space = old_pointer_space(); | 5141 OldSpace* space = old_pointer_space(); |
| 5140 PageIterator pages(space); | 5142 PageIterator pages(space); |
| 5141 | 5143 |
| 5142 store_buffer()->SortUniq(); | 5144 store_buffer()->SortUniq(); |
| 5143 | 5145 |
| 5144 while (pages.has_next()) { | 5146 while (pages.has_next()) { |
| 5145 Page* page = pages.next(); | 5147 Page* page = pages.next(); |
| 5146 Object** current = reinterpret_cast<Object**>(page->ObjectAreaStart()); | 5148 Object** current = reinterpret_cast<Object**>(page->area_start()); |
| 5147 | 5149 |
| 5148 Address end = page->ObjectAreaEnd(); | 5150 Address end = page->area_end(); |
| 5149 | 5151 |
| 5150 Object*** store_buffer_position = store_buffer()->Start(); | 5152 Object*** store_buffer_position = store_buffer()->Start(); |
| 5151 Object*** store_buffer_top = store_buffer()->Top(); | 5153 Object*** store_buffer_top = store_buffer()->Top(); |
| 5152 | 5154 |
| 5153 Object** limit = reinterpret_cast<Object**>(end); | 5155 Object** limit = reinterpret_cast<Object**>(end); |
| 5154 CheckStoreBuffer(this, | 5156 CheckStoreBuffer(this, |
| 5155 current, | 5157 current, |
| 5156 limit, | 5158 limit, |
| 5157 &store_buffer_position, | 5159 &store_buffer_position, |
| 5158 store_buffer_top, | 5160 store_buffer_top, |
| 5159 &EverythingsAPointer, | 5161 &EverythingsAPointer, |
| 5160 space->top(), | 5162 space->top(), |
| 5161 space->limit()); | 5163 space->limit()); |
| 5162 } | 5164 } |
| 5163 } | 5165 } |
| 5164 | 5166 |
| 5165 | 5167 |
| 5166 void Heap::MapSpaceCheckStoreBuffer() { | 5168 void Heap::MapSpaceCheckStoreBuffer() { |
| 5167 MapSpace* space = map_space(); | 5169 MapSpace* space = map_space(); |
| 5168 PageIterator pages(space); | 5170 PageIterator pages(space); |
| 5169 | 5171 |
| 5170 store_buffer()->SortUniq(); | 5172 store_buffer()->SortUniq(); |
| 5171 | 5173 |
| 5172 while (pages.has_next()) { | 5174 while (pages.has_next()) { |
| 5173 Page* page = pages.next(); | 5175 Page* page = pages.next(); |
| 5174 Object** current = reinterpret_cast<Object**>(page->ObjectAreaStart()); | 5176 Object** current = reinterpret_cast<Object**>(page->area_start()); |
| 5175 | 5177 |
| 5176 Address end = page->ObjectAreaEnd(); | 5178 Address end = page->area_end(); |
| 5177 | 5179 |
| 5178 Object*** store_buffer_position = store_buffer()->Start(); | 5180 Object*** store_buffer_position = store_buffer()->Start(); |
| 5179 Object*** store_buffer_top = store_buffer()->Top(); | 5181 Object*** store_buffer_top = store_buffer()->Top(); |
| 5180 | 5182 |
| 5181 Object** limit = reinterpret_cast<Object**>(end); | 5183 Object** limit = reinterpret_cast<Object**>(end); |
| 5182 CheckStoreBuffer(this, | 5184 CheckStoreBuffer(this, |
| 5183 current, | 5185 current, |
| 5184 limit, | 5186 limit, |
| 5185 &store_buffer_position, | 5187 &store_buffer_position, |
| 5186 store_buffer_top, | 5188 store_buffer_top, |
| (...skipping 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6703 isolate_->heap()->store_buffer()->Compact(); | 6705 isolate_->heap()->store_buffer()->Compact(); |
| 6704 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 6706 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |
| 6705 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 6707 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
| 6706 next = chunk->next_chunk(); | 6708 next = chunk->next_chunk(); |
| 6707 isolate_->memory_allocator()->Free(chunk); | 6709 isolate_->memory_allocator()->Free(chunk); |
| 6708 } | 6710 } |
| 6709 chunks_queued_for_free_ = NULL; | 6711 chunks_queued_for_free_ = NULL; |
| 6710 } | 6712 } |
| 6711 | 6713 |
| 6712 } } // namespace v8::internal | 6714 } } // namespace v8::internal |
| OLD | NEW |