Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: src/heap/heap-inl.h

Issue 437993003: Move a bunch of GC related files to heap/ subdirectory (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: make presubmit happy Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/heap/heap.cc ('k') | src/heap/incremental-marking.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_HEAP_INL_H_ 5 #ifndef V8_HEAP_HEAP_INL_H_
6 #define V8_HEAP_INL_H_ 6 #define V8_HEAP_HEAP_INL_H_
7 7
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
11 #include "src/cpu-profiler.h" 11 #include "src/cpu-profiler.h"
12 #include "src/heap.h" 12 #include "src/heap/heap.h"
13 #include "src/heap-profiler.h" 13 #include "src/heap-profiler.h"
14 #include "src/isolate.h" 14 #include "src/isolate.h"
15 #include "src/list-inl.h" 15 #include "src/list-inl.h"
16 #include "src/objects.h" 16 #include "src/objects.h"
17 #include "src/store-buffer.h" 17 #include "src/store-buffer.h"
18 #include "src/store-buffer-inl.h" 18 #include "src/store-buffer-inl.h"
19 19
20 namespace v8 { 20 namespace v8 {
21 namespace internal { 21 namespace internal {
22 22
(...skipping 17 matching lines...) Expand all
40 40
41 if ((rear_ - 2) < limit_) { 41 if ((rear_ - 2) < limit_) {
42 RelocateQueueHead(); 42 RelocateQueueHead();
43 emergency_stack_->Add(Entry(target, size)); 43 emergency_stack_->Add(Entry(target, size));
44 return; 44 return;
45 } 45 }
46 } 46 }
47 47
48 *(--rear_) = reinterpret_cast<intptr_t>(target); 48 *(--rear_) = reinterpret_cast<intptr_t>(target);
49 *(--rear_) = size; 49 *(--rear_) = size;
50 // Assert no overflow into live objects. 50 // Assert no overflow into live objects.
51 #ifdef DEBUG 51 #ifdef DEBUG
52 SemiSpace::AssertValidRange(target->GetIsolate()->heap()->new_space()->top(), 52 SemiSpace::AssertValidRange(target->GetIsolate()->heap()->new_space()->top(),
53 reinterpret_cast<Address>(rear_)); 53 reinterpret_cast<Address>(rear_));
54 #endif 54 #endif
55 } 55 }
56 56
57 57
58 void PromotionQueue::ActivateGuardIfOnTheSamePage() { 58 void PromotionQueue::ActivateGuardIfOnTheSamePage() {
59 guard_ = guard_ || 59 guard_ = guard_ ||
60 heap_->new_space()->active_space()->current_page()->address() == 60 heap_->new_space()->active_space()->current_page()->address() ==
61 GetHeadPage()->address(); 61 GetHeadPage()->address();
62 } 62 }
63 63
64 64
65 template<> 65 template <>
66 bool inline Heap::IsOneByte(Vector<const char> str, int chars) { 66 bool inline Heap::IsOneByte(Vector<const char> str, int chars) {
67 // TODO(dcarney): incorporate Latin-1 check when Latin-1 is supported? 67 // TODO(dcarney): incorporate Latin-1 check when Latin-1 is supported?
68 // ASCII only check. 68 // ASCII only check.
69 return chars == str.length(); 69 return chars == str.length();
70 } 70 }
71 71
72 72
73 template<> 73 template <>
74 bool inline Heap::IsOneByte(String* str, int chars) { 74 bool inline Heap::IsOneByte(String* str, int chars) {
75 return str->IsOneByteRepresentation(); 75 return str->IsOneByteRepresentation();
76 } 76 }
77 77
78 78
79 AllocationResult Heap::AllocateInternalizedStringFromUtf8( 79 AllocationResult Heap::AllocateInternalizedStringFromUtf8(
80 Vector<const char> str, int chars, uint32_t hash_field) { 80 Vector<const char> str, int chars, uint32_t hash_field) {
81 if (IsOneByte(str, chars)) { 81 if (IsOneByte(str, chars)) {
82 return AllocateOneByteInternalizedString( 82 return AllocateOneByteInternalizedString(Vector<const uint8_t>::cast(str),
83 Vector<const uint8_t>::cast(str), hash_field); 83 hash_field);
84 } 84 }
85 return AllocateInternalizedStringImpl<false>(str, chars, hash_field); 85 return AllocateInternalizedStringImpl<false>(str, chars, hash_field);
86 } 86 }
87 87
88 88
89 template<typename T> 89 template <typename T>
90 AllocationResult Heap::AllocateInternalizedStringImpl( 90 AllocationResult Heap::AllocateInternalizedStringImpl(T t, int chars,
91 T t, int chars, uint32_t hash_field) { 91 uint32_t hash_field) {
92 if (IsOneByte(t, chars)) { 92 if (IsOneByte(t, chars)) {
93 return AllocateInternalizedStringImpl<true>(t, chars, hash_field); 93 return AllocateInternalizedStringImpl<true>(t, chars, hash_field);
94 } 94 }
95 return AllocateInternalizedStringImpl<false>(t, chars, hash_field); 95 return AllocateInternalizedStringImpl<false>(t, chars, hash_field);
96 } 96 }
97 97
98 98
99 AllocationResult Heap::AllocateOneByteInternalizedString( 99 AllocationResult Heap::AllocateOneByteInternalizedString(
100 Vector<const uint8_t> str, 100 Vector<const uint8_t> str, uint32_t hash_field) {
101 uint32_t hash_field) {
102 CHECK_GE(String::kMaxLength, str.length()); 101 CHECK_GE(String::kMaxLength, str.length());
103 // Compute map and object size. 102 // Compute map and object size.
104 Map* map = ascii_internalized_string_map(); 103 Map* map = ascii_internalized_string_map();
105 int size = SeqOneByteString::SizeFor(str.length()); 104 int size = SeqOneByteString::SizeFor(str.length());
106 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED); 105 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED);
107 106
108 // Allocate string. 107 // Allocate string.
109 HeapObject* result; 108 HeapObject* result;
110 { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); 109 {
110 AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
111 if (!allocation.To(&result)) return allocation; 111 if (!allocation.To(&result)) return allocation;
112 } 112 }
113 113
114 // String maps are all immortal immovable objects. 114 // String maps are all immortal immovable objects.
115 result->set_map_no_write_barrier(map); 115 result->set_map_no_write_barrier(map);
116 // Set length and hash fields of the allocated string. 116 // Set length and hash fields of the allocated string.
117 String* answer = String::cast(result); 117 String* answer = String::cast(result);
118 answer->set_length(str.length()); 118 answer->set_length(str.length());
119 answer->set_hash_field(hash_field); 119 answer->set_hash_field(hash_field);
120 120
(...skipping 10 matching lines...) Expand all
131 AllocationResult Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str, 131 AllocationResult Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str,
132 uint32_t hash_field) { 132 uint32_t hash_field) {
133 CHECK_GE(String::kMaxLength, str.length()); 133 CHECK_GE(String::kMaxLength, str.length());
134 // Compute map and object size. 134 // Compute map and object size.
135 Map* map = internalized_string_map(); 135 Map* map = internalized_string_map();
136 int size = SeqTwoByteString::SizeFor(str.length()); 136 int size = SeqTwoByteString::SizeFor(str.length());
137 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED); 137 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED);
138 138
139 // Allocate string. 139 // Allocate string.
140 HeapObject* result; 140 HeapObject* result;
141 { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); 141 {
142 AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
142 if (!allocation.To(&result)) return allocation; 143 if (!allocation.To(&result)) return allocation;
143 } 144 }
144 145
145 result->set_map(map); 146 result->set_map(map);
146 // Set length and hash fields of the allocated string. 147 // Set length and hash fields of the allocated string.
147 String* answer = String::cast(result); 148 String* answer = String::cast(result);
148 answer->set_length(str.length()); 149 answer->set_length(str.length());
149 answer->set_hash_field(hash_field); 150 answer->set_hash_field(hash_field);
150 151
151 DCHECK_EQ(size, answer->Size()); 152 DCHECK_EQ(size, answer->Size());
(...skipping 16 matching lines...) Expand all
168 return CopyFixedDoubleArrayWithMap(src, src->map()); 169 return CopyFixedDoubleArrayWithMap(src, src->map());
169 } 170 }
170 171
171 172
172 AllocationResult Heap::CopyConstantPoolArray(ConstantPoolArray* src) { 173 AllocationResult Heap::CopyConstantPoolArray(ConstantPoolArray* src) {
173 if (src->length() == 0) return src; 174 if (src->length() == 0) return src;
174 return CopyConstantPoolArrayWithMap(src, src->map()); 175 return CopyConstantPoolArrayWithMap(src, src->map());
175 } 176 }
176 177
177 178
178 AllocationResult Heap::AllocateRaw(int size_in_bytes, 179 AllocationResult Heap::AllocateRaw(int size_in_bytes, AllocationSpace space,
179 AllocationSpace space,
180 AllocationSpace retry_space) { 180 AllocationSpace retry_space) {
181 DCHECK(AllowHandleAllocation::IsAllowed()); 181 DCHECK(AllowHandleAllocation::IsAllowed());
182 DCHECK(AllowHeapAllocation::IsAllowed()); 182 DCHECK(AllowHeapAllocation::IsAllowed());
183 DCHECK(gc_state_ == NOT_IN_GC); 183 DCHECK(gc_state_ == NOT_IN_GC);
184 #ifdef DEBUG 184 #ifdef DEBUG
185 if (FLAG_gc_interval >= 0 && 185 if (FLAG_gc_interval >= 0 && AllowAllocationFailure::IsAllowed(isolate_) &&
186 AllowAllocationFailure::IsAllowed(isolate_) &&
187 Heap::allocation_timeout_-- <= 0) { 186 Heap::allocation_timeout_-- <= 0) {
188 return AllocationResult::Retry(space); 187 return AllocationResult::Retry(space);
189 } 188 }
190 isolate_->counters()->objs_since_last_full()->Increment(); 189 isolate_->counters()->objs_since_last_full()->Increment();
191 isolate_->counters()->objs_since_last_young()->Increment(); 190 isolate_->counters()->objs_since_last_young()->Increment();
192 #endif 191 #endif
193 192
194 HeapObject* object; 193 HeapObject* object;
195 AllocationResult allocation; 194 AllocationResult allocation;
196 if (NEW_SPACE == space) { 195 if (NEW_SPACE == space) {
197 allocation = new_space_.AllocateRaw(size_in_bytes); 196 allocation = new_space_.AllocateRaw(size_in_bytes);
198 if (always_allocate() && 197 if (always_allocate() && allocation.IsRetry() && retry_space != NEW_SPACE) {
199 allocation.IsRetry() &&
200 retry_space != NEW_SPACE) {
201 space = retry_space; 198 space = retry_space;
202 } else { 199 } else {
203 if (allocation.To(&object)) { 200 if (allocation.To(&object)) {
204 OnAllocationEvent(object, size_in_bytes); 201 OnAllocationEvent(object, size_in_bytes);
205 } 202 }
206 return allocation; 203 return allocation;
207 } 204 }
208 } 205 }
209 206
210 if (OLD_POINTER_SPACE == space) { 207 if (OLD_POINTER_SPACE == space) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 248
252 if ((FLAG_dump_allocations_digest_at_alloc > 0) && 249 if ((FLAG_dump_allocations_digest_at_alloc > 0) &&
253 (--dump_allocations_hash_countdown_ == 0)) { 250 (--dump_allocations_hash_countdown_ == 0)) {
254 dump_allocations_hash_countdown_ = FLAG_dump_allocations_digest_at_alloc; 251 dump_allocations_hash_countdown_ = FLAG_dump_allocations_digest_at_alloc;
255 PrintAlloctionsHash(); 252 PrintAlloctionsHash();
256 } 253 }
257 } 254 }
258 } 255 }
259 256
260 257
261 void Heap::OnMoveEvent(HeapObject* target, 258 void Heap::OnMoveEvent(HeapObject* target, HeapObject* source,
262 HeapObject* source,
263 int size_in_bytes) { 259 int size_in_bytes) {
264 HeapProfiler* heap_profiler = isolate_->heap_profiler(); 260 HeapProfiler* heap_profiler = isolate_->heap_profiler();
265 if (heap_profiler->is_tracking_object_moves()) { 261 if (heap_profiler->is_tracking_object_moves()) {
266 heap_profiler->ObjectMoveEvent(source->address(), target->address(), 262 heap_profiler->ObjectMoveEvent(source->address(), target->address(),
267 size_in_bytes); 263 size_in_bytes);
268 } 264 }
269 265
270 if (isolate_->logger()->is_logging_code_events() || 266 if (isolate_->logger()->is_logging_code_events() ||
271 isolate_->cpu_profiler()->is_profiling()) { 267 isolate_->cpu_profiler()->is_profiling()) {
272 if (target->IsSharedFunctionInfo()) { 268 if (target->IsSharedFunctionInfo()) {
273 PROFILE(isolate_, SharedFunctionInfoMoveEvent( 269 PROFILE(isolate_, SharedFunctionInfoMoveEvent(source->address(),
274 source->address(), target->address())); 270 target->address()));
275 } 271 }
276 } 272 }
277 273
278 if (FLAG_verify_predictable) { 274 if (FLAG_verify_predictable) {
279 ++allocations_count_; 275 ++allocations_count_;
280 276
281 UpdateAllocationsHash(source); 277 UpdateAllocationsHash(source);
282 UpdateAllocationsHash(target); 278 UpdateAllocationsHash(target);
283 UpdateAllocationsHash(size_in_bytes); 279 UpdateAllocationsHash(size_in_bytes);
284 280
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 void Heap::PrintAlloctionsHash() { 314 void Heap::PrintAlloctionsHash() {
319 uint32_t hash = StringHasher::GetHashCore(raw_allocations_hash_); 315 uint32_t hash = StringHasher::GetHashCore(raw_allocations_hash_);
320 PrintF("\n### Allocations = %u, hash = 0x%08x\n", allocations_count_, hash); 316 PrintF("\n### Allocations = %u, hash = 0x%08x\n", allocations_count_, hash);
321 } 317 }
322 318
323 319
324 void Heap::FinalizeExternalString(String* string) { 320 void Heap::FinalizeExternalString(String* string) {
325 DCHECK(string->IsExternalString()); 321 DCHECK(string->IsExternalString());
326 v8::String::ExternalStringResourceBase** resource_addr = 322 v8::String::ExternalStringResourceBase** resource_addr =
327 reinterpret_cast<v8::String::ExternalStringResourceBase**>( 323 reinterpret_cast<v8::String::ExternalStringResourceBase**>(
328 reinterpret_cast<byte*>(string) + 324 reinterpret_cast<byte*>(string) + ExternalString::kResourceOffset -
329 ExternalString::kResourceOffset -
330 kHeapObjectTag); 325 kHeapObjectTag);
331 326
332 // Dispose of the C++ object if it has not already been disposed. 327 // Dispose of the C++ object if it has not already been disposed.
333 if (*resource_addr != NULL) { 328 if (*resource_addr != NULL) {
334 (*resource_addr)->Dispose(); 329 (*resource_addr)->Dispose();
335 *resource_addr = NULL; 330 *resource_addr = NULL;
336 } 331 }
337 } 332 }
338 333
339 334
340 bool Heap::InNewSpace(Object* object) { 335 bool Heap::InNewSpace(Object* object) {
341 bool result = new_space_.Contains(object); 336 bool result = new_space_.Contains(object);
342 DCHECK(!result || // Either not in new space 337 DCHECK(!result || // Either not in new space
343 gc_state_ != NOT_IN_GC || // ... or in the middle of GC 338 gc_state_ != NOT_IN_GC || // ... or in the middle of GC
344 InToSpace(object)); // ... or in to-space (where we allocate). 339 InToSpace(object)); // ... or in to-space (where we allocate).
345 return result; 340 return result;
346 } 341 }
347 342
348 343
349 bool Heap::InNewSpace(Address address) { 344 bool Heap::InNewSpace(Address address) { return new_space_.Contains(address); }
350 return new_space_.Contains(address);
351 }
352 345
353 346
354 bool Heap::InFromSpace(Object* object) { 347 bool Heap::InFromSpace(Object* object) {
355 return new_space_.FromSpaceContains(object); 348 return new_space_.FromSpaceContains(object);
356 } 349 }
357 350
358 351
359 bool Heap::InToSpace(Object* object) { 352 bool Heap::InToSpace(Object* object) {
360 return new_space_.ToSpaceContains(object); 353 return new_space_.ToSpaceContains(object);
361 } 354 }
(...skipping 22 matching lines...) Expand all
384 bool Heap::OldGenerationAllocationLimitReached() { 377 bool Heap::OldGenerationAllocationLimitReached() {
385 if (!incremental_marking()->IsStopped()) return false; 378 if (!incremental_marking()->IsStopped()) return false;
386 return OldGenerationSpaceAvailable() < 0; 379 return OldGenerationSpaceAvailable() < 0;
387 } 380 }
388 381
389 382
390 bool Heap::ShouldBePromoted(Address old_address, int object_size) { 383 bool Heap::ShouldBePromoted(Address old_address, int object_size) {
391 NewSpacePage* page = NewSpacePage::FromAddress(old_address); 384 NewSpacePage* page = NewSpacePage::FromAddress(old_address);
392 Address age_mark = new_space_.age_mark(); 385 Address age_mark = new_space_.age_mark();
393 return page->IsFlagSet(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK) && 386 return page->IsFlagSet(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK) &&
394 (!page->ContainsLimit(age_mark) || old_address < age_mark); 387 (!page->ContainsLimit(age_mark) || old_address < age_mark);
395 } 388 }
396 389
397 390
398 void Heap::RecordWrite(Address address, int offset) { 391 void Heap::RecordWrite(Address address, int offset) {
399 if (!InNewSpace(address)) store_buffer_.Mark(address + offset); 392 if (!InNewSpace(address)) store_buffer_.Mark(address + offset);
400 } 393 }
401 394
402 395
403 void Heap::RecordWrites(Address address, int start, int len) { 396 void Heap::RecordWrites(Address address, int start, int len) {
404 if (!InNewSpace(address)) { 397 if (!InNewSpace(address)) {
405 for (int i = 0; i < len; i++) { 398 for (int i = 0; i < len; i++) {
406 store_buffer_.Mark(address + start + i * kPointerSize); 399 store_buffer_.Mark(address + start + i * kPointerSize);
407 } 400 }
408 } 401 }
409 } 402 }
410 403
411 404
412 OldSpace* Heap::TargetSpace(HeapObject* object) { 405 OldSpace* Heap::TargetSpace(HeapObject* object) {
413 InstanceType type = object->map()->instance_type(); 406 InstanceType type = object->map()->instance_type();
414 AllocationSpace space = TargetSpaceId(type); 407 AllocationSpace space = TargetSpaceId(type);
415 return (space == OLD_POINTER_SPACE) 408 return (space == OLD_POINTER_SPACE) ? old_pointer_space_ : old_data_space_;
416 ? old_pointer_space_
417 : old_data_space_;
418 } 409 }
419 410
420 411
421 AllocationSpace Heap::TargetSpaceId(InstanceType type) { 412 AllocationSpace Heap::TargetSpaceId(InstanceType type) {
422 // Heap numbers and sequential strings are promoted to old data space, all 413 // Heap numbers and sequential strings are promoted to old data space, all
423 // other object types are promoted to old pointer space. We do not use 414 // other object types are promoted to old pointer space. We do not use
424 // object->IsHeapNumber() and object->IsSeqString() because we already 415 // object->IsHeapNumber() and object->IsSeqString() because we already
425 // know that object has the heap object tag. 416 // know that object has the heap object tag.
426 417
427 // These objects are never allocated in new space. 418 // These objects are never allocated in new space.
428 DCHECK(type != MAP_TYPE); 419 DCHECK(type != MAP_TYPE);
429 DCHECK(type != CODE_TYPE); 420 DCHECK(type != CODE_TYPE);
430 DCHECK(type != ODDBALL_TYPE); 421 DCHECK(type != ODDBALL_TYPE);
431 DCHECK(type != CELL_TYPE); 422 DCHECK(type != CELL_TYPE);
432 DCHECK(type != PROPERTY_CELL_TYPE); 423 DCHECK(type != PROPERTY_CELL_TYPE);
433 424
434 if (type <= LAST_NAME_TYPE) { 425 if (type <= LAST_NAME_TYPE) {
435 if (type == SYMBOL_TYPE) return OLD_POINTER_SPACE; 426 if (type == SYMBOL_TYPE) return OLD_POINTER_SPACE;
436 DCHECK(type < FIRST_NONSTRING_TYPE); 427 DCHECK(type < FIRST_NONSTRING_TYPE);
437 // There are four string representations: sequential strings, external 428 // There are four string representations: sequential strings, external
438 // strings, cons strings, and sliced strings. 429 // strings, cons strings, and sliced strings.
439 // Only the latter two contain non-map-word pointers to heap objects. 430 // Only the latter two contain non-map-word pointers to heap objects.
440 return ((type & kIsIndirectStringMask) == kIsIndirectStringTag) 431 return ((type & kIsIndirectStringMask) == kIsIndirectStringTag)
441 ? OLD_POINTER_SPACE 432 ? OLD_POINTER_SPACE
442 : OLD_DATA_SPACE; 433 : OLD_DATA_SPACE;
443 } else { 434 } else {
444 return (type <= LAST_DATA_TYPE) ? OLD_DATA_SPACE : OLD_POINTER_SPACE; 435 return (type <= LAST_DATA_TYPE) ? OLD_DATA_SPACE : OLD_POINTER_SPACE;
445 } 436 }
446 } 437 }
447 438
448 439
449 bool Heap::AllowedToBeMigrated(HeapObject* obj, AllocationSpace dst) { 440 bool Heap::AllowedToBeMigrated(HeapObject* obj, AllocationSpace dst) {
450 // Object migration is governed by the following rules: 441 // Object migration is governed by the following rules:
451 // 442 //
452 // 1) Objects in new-space can be migrated to one of the old spaces 443 // 1) Objects in new-space can be migrated to one of the old spaces
(...skipping 30 matching lines...) Expand all
483 return false; 474 return false;
484 case INVALID_SPACE: 475 case INVALID_SPACE:
485 break; 476 break;
486 } 477 }
487 UNREACHABLE(); 478 UNREACHABLE();
488 return false; 479 return false;
489 } 480 }
490 481
491 482
492 void Heap::CopyBlock(Address dst, Address src, int byte_size) { 483 void Heap::CopyBlock(Address dst, Address src, int byte_size) {
493 CopyWords(reinterpret_cast<Object**>(dst), 484 CopyWords(reinterpret_cast<Object**>(dst), reinterpret_cast<Object**>(src),
494 reinterpret_cast<Object**>(src),
495 static_cast<size_t>(byte_size / kPointerSize)); 485 static_cast<size_t>(byte_size / kPointerSize));
496 } 486 }
497 487
498 488
499 void Heap::MoveBlock(Address dst, Address src, int byte_size) { 489 void Heap::MoveBlock(Address dst, Address src, int byte_size) {
500 DCHECK(IsAligned(byte_size, kPointerSize)); 490 DCHECK(IsAligned(byte_size, kPointerSize));
501 491
502 int size_in_words = byte_size / kPointerSize; 492 int size_in_words = byte_size / kPointerSize;
503 493
504 if ((dst < src) || (dst >= (src + byte_size))) { 494 if ((dst < src) || (dst >= (src + byte_size))) {
505 Object** src_slot = reinterpret_cast<Object**>(src); 495 Object** src_slot = reinterpret_cast<Object**>(src);
506 Object** dst_slot = reinterpret_cast<Object**>(dst); 496 Object** dst_slot = reinterpret_cast<Object**>(dst);
507 Object** end_slot = src_slot + size_in_words; 497 Object** end_slot = src_slot + size_in_words;
508 498
509 while (src_slot != end_slot) { 499 while (src_slot != end_slot) {
510 *dst_slot++ = *src_slot++; 500 *dst_slot++ = *src_slot++;
511 } 501 }
512 } else { 502 } else {
513 MemMove(dst, src, static_cast<size_t>(byte_size)); 503 MemMove(dst, src, static_cast<size_t>(byte_size));
514 } 504 }
515 } 505 }
516 506
517 507
518 void Heap::ScavengePointer(HeapObject** p) { 508 void Heap::ScavengePointer(HeapObject** p) { ScavengeObject(p, *p); }
519 ScavengeObject(p, *p);
520 }
521 509
522 510
523 AllocationMemento* Heap::FindAllocationMemento(HeapObject* object) { 511 AllocationMemento* Heap::FindAllocationMemento(HeapObject* object) {
524 // Check if there is potentially a memento behind the object. If 512 // Check if there is potentially a memento behind the object. If
525 // the last word of the momento is on another page we return 513 // the last word of the momento is on another page we return
526 // immediately. 514 // immediately.
527 Address object_address = object->address(); 515 Address object_address = object->address();
528 Address memento_address = object_address + object->Size(); 516 Address memento_address = object_address + object->Size();
529 Address last_memento_word_address = memento_address + kPointerSize; 517 Address last_memento_word_address = memento_address + kPointerSize;
530 if (!NewSpacePage::OnSamePage(object_address, 518 if (!NewSpacePage::OnSamePage(object_address, last_memento_word_address)) {
531 last_memento_word_address)) {
532 return NULL; 519 return NULL;
533 } 520 }
534 521
535 HeapObject* candidate = HeapObject::FromAddress(memento_address); 522 HeapObject* candidate = HeapObject::FromAddress(memento_address);
536 if (candidate->map() != allocation_memento_map()) return NULL; 523 if (candidate->map() != allocation_memento_map()) return NULL;
537 524
538 // Either the object is the last object in the new space, or there is another 525 // Either the object is the last object in the new space, or there is another
539 // object of at least word size (the header map word) following it, so 526 // object of at least word size (the header map word) following it, so
540 // suffices to compare ptr and top here. Note that technically we do not have 527 // suffices to compare ptr and top here. Note that technically we do not have
541 // to compare with the current top pointer of the from space page during GC, 528 // to compare with the current top pointer of the from space page during GC,
(...skipping 12 matching lines...) Expand all
554 return memento; 541 return memento;
555 } 542 }
556 543
557 544
558 void Heap::UpdateAllocationSiteFeedback(HeapObject* object, 545 void Heap::UpdateAllocationSiteFeedback(HeapObject* object,
559 ScratchpadSlotMode mode) { 546 ScratchpadSlotMode mode) {
560 Heap* heap = object->GetHeap(); 547 Heap* heap = object->GetHeap();
561 DCHECK(heap->InFromSpace(object)); 548 DCHECK(heap->InFromSpace(object));
562 549
563 if (!FLAG_allocation_site_pretenuring || 550 if (!FLAG_allocation_site_pretenuring ||
564 !AllocationSite::CanTrack(object->map()->instance_type())) return; 551 !AllocationSite::CanTrack(object->map()->instance_type()))
552 return;
565 553
566 AllocationMemento* memento = heap->FindAllocationMemento(object); 554 AllocationMemento* memento = heap->FindAllocationMemento(object);
567 if (memento == NULL) return; 555 if (memento == NULL) return;
568 556
569 if (memento->GetAllocationSite()->IncrementMementoFoundCount()) { 557 if (memento->GetAllocationSite()->IncrementMementoFoundCount()) {
570 heap->AddAllocationSiteToScratchpad(memento->GetAllocationSite(), mode); 558 heap->AddAllocationSiteToScratchpad(memento->GetAllocationSite(), mode);
571 } 559 }
572 } 560 }
573 561
574 562
(...skipping 17 matching lines...) Expand all
592 580
593 UpdateAllocationSiteFeedback(object, IGNORE_SCRATCHPAD_SLOT); 581 UpdateAllocationSiteFeedback(object, IGNORE_SCRATCHPAD_SLOT);
594 582
595 // AllocationMementos are unrooted and shouldn't survive a scavenge 583 // AllocationMementos are unrooted and shouldn't survive a scavenge
596 DCHECK(object->map() != object->GetHeap()->allocation_memento_map()); 584 DCHECK(object->map() != object->GetHeap()->allocation_memento_map());
597 // Call the slow part of scavenge object. 585 // Call the slow part of scavenge object.
598 return ScavengeObjectSlow(p, object); 586 return ScavengeObjectSlow(p, object);
599 } 587 }
600 588
601 589
602 bool Heap::CollectGarbage(AllocationSpace space, 590 bool Heap::CollectGarbage(AllocationSpace space, const char* gc_reason,
603 const char* gc_reason,
604 const v8::GCCallbackFlags callbackFlags) { 591 const v8::GCCallbackFlags callbackFlags) {
605 const char* collector_reason = NULL; 592 const char* collector_reason = NULL;
606 GarbageCollector collector = SelectGarbageCollector(space, &collector_reason); 593 GarbageCollector collector = SelectGarbageCollector(space, &collector_reason);
607 return CollectGarbage(collector, gc_reason, collector_reason, callbackFlags); 594 return CollectGarbage(collector, gc_reason, collector_reason, callbackFlags);
608 } 595 }
609 596
610 597
611 Isolate* Heap::isolate() { 598 Isolate* Heap::isolate() {
612 return reinterpret_cast<Isolate*>(reinterpret_cast<intptr_t>(this) - 599 return reinterpret_cast<Isolate*>(
600 reinterpret_cast<intptr_t>(this) -
613 reinterpret_cast<size_t>(reinterpret_cast<Isolate*>(4)->heap()) + 4); 601 reinterpret_cast<size_t>(reinterpret_cast<Isolate*>(4)->heap()) + 4);
614 } 602 }
615 603
616 604
617 // Calls the FUNCTION_CALL function and retries it up to three times 605 // Calls the FUNCTION_CALL function and retries it up to three times
618 // to guarantee that any allocations performed during the call will 606 // to guarantee that any allocations performed during the call will
619 // succeed if there's enough memory. 607 // succeed if there's enough memory.
620 608
621 // Warning: Do not use the identifiers __object__, __maybe_object__ or 609 // Warning: Do not use the identifiers __object__, __maybe_object__ or
622 // __scope__ in a call to this macro. 610 // __scope__ in a call to this macro.
623 611
624 #define RETURN_OBJECT_UNLESS_RETRY(ISOLATE, RETURN_VALUE) \ 612 #define RETURN_OBJECT_UNLESS_RETRY(ISOLATE, RETURN_VALUE) \
625 if (__allocation__.To(&__object__)) { \ 613 if (__allocation__.To(&__object__)) { \
626 DCHECK(__object__ != (ISOLATE)->heap()->exception()); \ 614 DCHECK(__object__ != (ISOLATE)->heap()->exception()); \
627 RETURN_VALUE; \ 615 RETURN_VALUE; \
628 } 616 }
629 617
630 #define CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY) \ 618 #define CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY) \
631 do { \ 619 do { \
632 AllocationResult __allocation__ = FUNCTION_CALL; \ 620 AllocationResult __allocation__ = FUNCTION_CALL; \
633 Object* __object__ = NULL; \ 621 Object* __object__ = NULL; \
634 RETURN_OBJECT_UNLESS_RETRY(ISOLATE, RETURN_VALUE) \ 622 RETURN_OBJECT_UNLESS_RETRY(ISOLATE, RETURN_VALUE) \
635 (ISOLATE)->heap()->CollectGarbage(__allocation__.RetrySpace(), \ 623 (ISOLATE)->heap()->CollectGarbage(__allocation__.RetrySpace(), \
636 "allocation failure"); \ 624 "allocation failure"); \
637 __allocation__ = FUNCTION_CALL; \ 625 __allocation__ = FUNCTION_CALL; \
638 RETURN_OBJECT_UNLESS_RETRY(ISOLATE, RETURN_VALUE) \ 626 RETURN_OBJECT_UNLESS_RETRY(ISOLATE, RETURN_VALUE) \
639 (ISOLATE)->counters()->gc_last_resort_from_handles()->Increment(); \ 627 (ISOLATE)->counters()->gc_last_resort_from_handles()->Increment(); \
640 (ISOLATE)->heap()->CollectAllAvailableGarbage("last resort gc"); \ 628 (ISOLATE)->heap()->CollectAllAvailableGarbage("last resort gc"); \
641 { \ 629 { \
642 AlwaysAllocateScope __scope__(ISOLATE); \ 630 AlwaysAllocateScope __scope__(ISOLATE); \
643 __allocation__ = FUNCTION_CALL; \ 631 __allocation__ = FUNCTION_CALL; \
644 } \ 632 } \
645 RETURN_OBJECT_UNLESS_RETRY(ISOLATE, RETURN_VALUE) \ 633 RETURN_OBJECT_UNLESS_RETRY(ISOLATE, RETURN_VALUE) \
646 /* TODO(1181417): Fix this. */ \ 634 /* TODO(1181417): Fix this. */ \
647 v8::internal::Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); \ 635 v8::internal::Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); \
648 RETURN_EMPTY; \ 636 RETURN_EMPTY; \
649 } while (false) 637 } while (false)
650 638
651 #define CALL_AND_RETRY_OR_DIE( \ 639 #define CALL_AND_RETRY_OR_DIE(ISOLATE, FUNCTION_CALL, RETURN_VALUE, \
652 ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY) \ 640 RETURN_EMPTY) \
653 CALL_AND_RETRY( \ 641 CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY)
654 ISOLATE, \
655 FUNCTION_CALL, \
656 RETURN_VALUE, \
657 RETURN_EMPTY)
658 642
659 #define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE) \ 643 #define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE) \
660 CALL_AND_RETRY_OR_DIE(ISOLATE, \ 644 CALL_AND_RETRY_OR_DIE(ISOLATE, FUNCTION_CALL, \
661 FUNCTION_CALL, \
662 return Handle<TYPE>(TYPE::cast(__object__), ISOLATE), \ 645 return Handle<TYPE>(TYPE::cast(__object__), ISOLATE), \
663 return Handle<TYPE>()) \ 646 return Handle<TYPE>())
664 647
665 648
666 #define CALL_HEAP_FUNCTION_VOID(ISOLATE, FUNCTION_CALL) \ 649 #define CALL_HEAP_FUNCTION_VOID(ISOLATE, FUNCTION_CALL) \
667 CALL_AND_RETRY_OR_DIE(ISOLATE, FUNCTION_CALL, return, return) 650 CALL_AND_RETRY_OR_DIE(ISOLATE, FUNCTION_CALL, return, return)
668 651
669 652
670 void ExternalStringTable::AddString(String* string) { 653 void ExternalStringTable::AddString(String* string) {
671 DCHECK(string->IsExternalString()); 654 DCHECK(string->IsExternalString());
672 if (heap_->InNewSpace(string)) { 655 if (heap_->InNewSpace(string)) {
673 new_space_strings_.Add(string); 656 new_space_strings_.Add(string);
674 } else { 657 } else {
675 old_space_strings_.Add(string); 658 old_space_strings_.Add(string);
676 } 659 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 isolate->heap()->no_weak_object_verification_scope_depth_--; 752 isolate->heap()->no_weak_object_verification_scope_depth_--;
770 } 753 }
771 #endif 754 #endif
772 755
773 756
774 GCCallbacksScope::GCCallbacksScope(Heap* heap) : heap_(heap) { 757 GCCallbacksScope::GCCallbacksScope(Heap* heap) : heap_(heap) {
775 heap_->gc_callbacks_depth_++; 758 heap_->gc_callbacks_depth_++;
776 } 759 }
777 760
778 761
779 GCCallbacksScope::~GCCallbacksScope() { 762 GCCallbacksScope::~GCCallbacksScope() { heap_->gc_callbacks_depth_--; }
780 heap_->gc_callbacks_depth_--;
781 }
782 763
783 764
784 bool GCCallbacksScope::CheckReenter() { 765 bool GCCallbacksScope::CheckReenter() {
785 return heap_->gc_callbacks_depth_ == 1; 766 return heap_->gc_callbacks_depth_ == 1;
786 } 767 }
787 768
788 769
789 void VerifyPointersVisitor::VisitPointers(Object** start, Object** end) { 770 void VerifyPointersVisitor::VisitPointers(Object** start, Object** end) {
790 for (Object** current = start; current < end; current++) { 771 for (Object** current = start; current < end; current++) {
791 if ((*current)->IsHeapObject()) { 772 if ((*current)->IsHeapObject()) {
792 HeapObject* object = HeapObject::cast(*current); 773 HeapObject* object = HeapObject::cast(*current);
793 CHECK(object->GetIsolate()->heap()->Contains(object)); 774 CHECK(object->GetIsolate()->heap()->Contains(object));
794 CHECK(object->map()->IsMap()); 775 CHECK(object->map()->IsMap());
795 } 776 }
796 } 777 }
797 } 778 }
798 779
799 780
800 void VerifySmisVisitor::VisitPointers(Object** start, Object** end) { 781 void VerifySmisVisitor::VisitPointers(Object** start, Object** end) {
801 for (Object** current = start; current < end; current++) { 782 for (Object** current = start; current < end; current++) {
802 CHECK((*current)->IsSmi()); 783 CHECK((*current)->IsSmi());
803 } 784 }
804 } 785 }
786 }
787 } // namespace v8::internal
805 788
806 789 #endif // V8_HEAP_HEAP_INL_H_
807 } } // namespace v8::internal
808
809 #endif // V8_HEAP_INL_H_
OLDNEW
« no previous file with comments | « src/heap/heap.cc ('k') | src/heap/incremental-marking.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698