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

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

Issue 4100005: Version 2.5.2 (Closed)
Patch Set: Created 10 years, 1 month 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
« no previous file with comments | « src/heap.cc ('k') | src/ia32/assembler-ia32.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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 17 matching lines...) Expand all
28 #ifndef V8_HEAP_INL_H_ 28 #ifndef V8_HEAP_INL_H_
29 #define V8_HEAP_INL_H_ 29 #define V8_HEAP_INL_H_
30 30
31 #include "heap.h" 31 #include "heap.h"
32 #include "objects.h" 32 #include "objects.h"
33 #include "v8-counters.h" 33 #include "v8-counters.h"
34 34
35 namespace v8 { 35 namespace v8 {
36 namespace internal { 36 namespace internal {
37 37
38 void Heap::UpdateOldSpaceLimits() {
39 intptr_t old_gen_size = PromotedSpaceSize();
40 old_gen_promotion_limit_ =
41 old_gen_size + Max(kMinimumPromotionLimit, old_gen_size / 3);
42 old_gen_allocation_limit_ =
43 old_gen_size + Max(kMinimumAllocationLimit, old_gen_size / 2);
44 old_gen_exhausted_ = false;
45 }
46
47
48 int Heap::MaxObjectSizeInPagedSpace() { 38 int Heap::MaxObjectSizeInPagedSpace() {
49 return Page::kMaxHeapObjectSize; 39 return Page::kMaxHeapObjectSize;
50 } 40 }
51 41
52 42
53 Object* Heap::AllocateSymbol(Vector<const char> str, 43 MaybeObject* Heap::AllocateSymbol(Vector<const char> str,
54 int chars, 44 int chars,
55 uint32_t hash_field) { 45 uint32_t hash_field) {
56 unibrow::Utf8InputBuffer<> buffer(str.start(), 46 unibrow::Utf8InputBuffer<> buffer(str.start(),
57 static_cast<unsigned>(str.length())); 47 static_cast<unsigned>(str.length()));
58 return AllocateInternalSymbol(&buffer, chars, hash_field); 48 return AllocateInternalSymbol(&buffer, chars, hash_field);
59 } 49 }
60 50
61 51
62 Object* Heap::CopyFixedArray(FixedArray* src) { 52 MaybeObject* Heap::CopyFixedArray(FixedArray* src) {
63 return CopyFixedArrayWithMap(src, src->map()); 53 return CopyFixedArrayWithMap(src, src->map());
64 } 54 }
65 55
66 56
67 Object* Heap::AllocateRaw(int size_in_bytes, 57 MaybeObject* Heap::AllocateRaw(int size_in_bytes,
68 AllocationSpace space, 58 AllocationSpace space,
69 AllocationSpace retry_space) { 59 AllocationSpace retry_space) {
70 ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC); 60 ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC);
71 ASSERT(space != NEW_SPACE || 61 ASSERT(space != NEW_SPACE ||
72 retry_space == OLD_POINTER_SPACE || 62 retry_space == OLD_POINTER_SPACE ||
73 retry_space == OLD_DATA_SPACE || 63 retry_space == OLD_DATA_SPACE ||
74 retry_space == LO_SPACE); 64 retry_space == LO_SPACE);
75 #ifdef DEBUG 65 #ifdef DEBUG
76 if (FLAG_gc_interval >= 0 && 66 if (FLAG_gc_interval >= 0 &&
77 !disallow_allocation_failure_ && 67 !disallow_allocation_failure_ &&
78 Heap::allocation_timeout_-- <= 0) { 68 Heap::allocation_timeout_-- <= 0) {
79 return Failure::RetryAfterGC(space); 69 return Failure::RetryAfterGC(space);
80 } 70 }
81 Counters::objs_since_last_full.Increment(); 71 Counters::objs_since_last_full.Increment();
82 Counters::objs_since_last_young.Increment(); 72 Counters::objs_since_last_young.Increment();
83 #endif 73 #endif
84 Object* result; 74 MaybeObject* result;
85 if (NEW_SPACE == space) { 75 if (NEW_SPACE == space) {
86 result = new_space_.AllocateRaw(size_in_bytes); 76 result = new_space_.AllocateRaw(size_in_bytes);
87 if (always_allocate() && result->IsFailure()) { 77 if (always_allocate() && result->IsFailure()) {
88 space = retry_space; 78 space = retry_space;
89 } else { 79 } else {
90 return result; 80 return result;
91 } 81 }
92 } 82 }
93 83
94 if (OLD_POINTER_SPACE == space) { 84 if (OLD_POINTER_SPACE == space) {
95 result = old_pointer_space_->AllocateRaw(size_in_bytes); 85 result = old_pointer_space_->AllocateRaw(size_in_bytes);
96 } else if (OLD_DATA_SPACE == space) { 86 } else if (OLD_DATA_SPACE == space) {
97 result = old_data_space_->AllocateRaw(size_in_bytes); 87 result = old_data_space_->AllocateRaw(size_in_bytes);
98 } else if (CODE_SPACE == space) { 88 } else if (CODE_SPACE == space) {
99 result = code_space_->AllocateRaw(size_in_bytes); 89 result = code_space_->AllocateRaw(size_in_bytes);
100 } else if (LO_SPACE == space) { 90 } else if (LO_SPACE == space) {
101 result = lo_space_->AllocateRaw(size_in_bytes); 91 result = lo_space_->AllocateRaw(size_in_bytes);
102 } else if (CELL_SPACE == space) { 92 } else if (CELL_SPACE == space) {
103 result = cell_space_->AllocateRaw(size_in_bytes); 93 result = cell_space_->AllocateRaw(size_in_bytes);
104 } else { 94 } else {
105 ASSERT(MAP_SPACE == space); 95 ASSERT(MAP_SPACE == space);
106 result = map_space_->AllocateRaw(size_in_bytes); 96 result = map_space_->AllocateRaw(size_in_bytes);
107 } 97 }
108 if (result->IsFailure()) old_gen_exhausted_ = true; 98 if (result->IsFailure()) old_gen_exhausted_ = true;
109 return result; 99 return result;
110 } 100 }
111 101
112 102
113 Object* Heap::NumberFromInt32(int32_t value) { 103 MaybeObject* Heap::NumberFromInt32(int32_t value) {
114 if (Smi::IsValid(value)) return Smi::FromInt(value); 104 if (Smi::IsValid(value)) return Smi::FromInt(value);
115 // Bypass NumberFromDouble to avoid various redundant checks. 105 // Bypass NumberFromDouble to avoid various redundant checks.
116 return AllocateHeapNumber(FastI2D(value)); 106 return AllocateHeapNumber(FastI2D(value));
117 } 107 }
118 108
119 109
120 Object* Heap::NumberFromUint32(uint32_t value) { 110 MaybeObject* Heap::NumberFromUint32(uint32_t value) {
121 if ((int32_t)value >= 0 && Smi::IsValid((int32_t)value)) { 111 if ((int32_t)value >= 0 && Smi::IsValid((int32_t)value)) {
122 return Smi::FromInt((int32_t)value); 112 return Smi::FromInt((int32_t)value);
123 } 113 }
124 // Bypass NumberFromDouble to avoid various redundant checks. 114 // Bypass NumberFromDouble to avoid various redundant checks.
125 return AllocateHeapNumber(FastUI2D(value)); 115 return AllocateHeapNumber(FastUI2D(value));
126 } 116 }
127 117
128 118
129 void Heap::FinalizeExternalString(String* string) { 119 void Heap::FinalizeExternalString(String* string) {
130 ASSERT(string->IsExternalString()); 120 ASSERT(string->IsExternalString());
131 v8::String::ExternalStringResourceBase** resource_addr = 121 v8::String::ExternalStringResourceBase** resource_addr =
132 reinterpret_cast<v8::String::ExternalStringResourceBase**>( 122 reinterpret_cast<v8::String::ExternalStringResourceBase**>(
133 reinterpret_cast<byte*>(string) + 123 reinterpret_cast<byte*>(string) +
134 ExternalString::kResourceOffset - 124 ExternalString::kResourceOffset -
135 kHeapObjectTag); 125 kHeapObjectTag);
136 126
137 // Dispose of the C++ object if it has not already been disposed. 127 // Dispose of the C++ object if it has not already been disposed.
138 if (*resource_addr != NULL) { 128 if (*resource_addr != NULL) {
139 (*resource_addr)->Dispose(); 129 (*resource_addr)->Dispose();
140 } 130 }
141 131
142 // Clear the resource pointer in the string. 132 // Clear the resource pointer in the string.
143 *resource_addr = NULL; 133 *resource_addr = NULL;
144 } 134 }
145 135
146 136
147 Object* Heap::AllocateRawMap() { 137 MaybeObject* Heap::AllocateRawMap() {
148 #ifdef DEBUG 138 #ifdef DEBUG
149 Counters::objs_since_last_full.Increment(); 139 Counters::objs_since_last_full.Increment();
150 Counters::objs_since_last_young.Increment(); 140 Counters::objs_since_last_young.Increment();
151 #endif 141 #endif
152 Object* result = map_space_->AllocateRaw(Map::kSize); 142 MaybeObject* result = map_space_->AllocateRaw(Map::kSize);
153 if (result->IsFailure()) old_gen_exhausted_ = true; 143 if (result->IsFailure()) old_gen_exhausted_ = true;
154 #ifdef DEBUG 144 #ifdef DEBUG
155 if (!result->IsFailure()) { 145 if (!result->IsFailure()) {
156 // Maps have their own alignment. 146 // Maps have their own alignment.
157 CHECK((reinterpret_cast<intptr_t>(result) & kMapAlignmentMask) == 147 CHECK((reinterpret_cast<intptr_t>(result) & kMapAlignmentMask) ==
158 static_cast<intptr_t>(kHeapObjectTag)); 148 static_cast<intptr_t>(kHeapObjectTag));
159 } 149 }
160 #endif 150 #endif
161 return result; 151 return result;
162 } 152 }
163 153
164 154
165 Object* Heap::AllocateRawCell() { 155 MaybeObject* Heap::AllocateRawCell() {
166 #ifdef DEBUG 156 #ifdef DEBUG
167 Counters::objs_since_last_full.Increment(); 157 Counters::objs_since_last_full.Increment();
168 Counters::objs_since_last_young.Increment(); 158 Counters::objs_since_last_young.Increment();
169 #endif 159 #endif
170 Object* result = cell_space_->AllocateRaw(JSGlobalPropertyCell::kSize); 160 MaybeObject* result = cell_space_->AllocateRaw(JSGlobalPropertyCell::kSize);
171 if (result->IsFailure()) old_gen_exhausted_ = true; 161 if (result->IsFailure()) old_gen_exhausted_ = true;
172 return result; 162 return result;
173 } 163 }
174 164
175 165
176 bool Heap::InNewSpace(Object* object) { 166 bool Heap::InNewSpace(Object* object) {
177 bool result = new_space_.Contains(object); 167 bool result = new_space_.Contains(object);
178 ASSERT(!result || // Either not in new space 168 ASSERT(!result || // Either not in new space
179 gc_state_ != NOT_IN_GC || // ... or in the middle of GC 169 gc_state_ != NOT_IN_GC || // ... or in the middle of GC
180 InToSpace(object)); // ... or in to-space (where we allocate). 170 InToSpace(object)); // ... or in to-space (where we allocate).
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 if (first_word.IsForwardingAddress()) { 323 if (first_word.IsForwardingAddress()) {
334 *p = first_word.ToForwardingAddress(); 324 *p = first_word.ToForwardingAddress();
335 return; 325 return;
336 } 326 }
337 327
338 // Call the slow part of scavenge object. 328 // Call the slow part of scavenge object.
339 return ScavengeObjectSlow(p, object); 329 return ScavengeObjectSlow(p, object);
340 } 330 }
341 331
342 332
343 Object* Heap::PrepareForCompare(String* str) { 333 MaybeObject* Heap::PrepareForCompare(String* str) {
344 // Always flatten small strings and force flattening of long strings 334 // Always flatten small strings and force flattening of long strings
345 // after we have accumulated a certain amount we failed to flatten. 335 // after we have accumulated a certain amount we failed to flatten.
346 static const int kMaxAlwaysFlattenLength = 32; 336 static const int kMaxAlwaysFlattenLength = 32;
347 static const int kFlattenLongThreshold = 16*KB; 337 static const int kFlattenLongThreshold = 16*KB;
348 338
349 const int length = str->length(); 339 const int length = str->length();
350 Object* obj = str->TryFlatten(); 340 MaybeObject* obj = str->TryFlatten();
351 if (length <= kMaxAlwaysFlattenLength || 341 if (length <= kMaxAlwaysFlattenLength ||
352 unflattened_strings_length_ >= kFlattenLongThreshold) { 342 unflattened_strings_length_ >= kFlattenLongThreshold) {
353 return obj; 343 return obj;
354 } 344 }
355 if (obj->IsFailure()) { 345 if (obj->IsFailure()) {
356 unflattened_strings_length_ += length; 346 unflattened_strings_length_ += length;
357 } 347 }
358 return str; 348 return str;
359 } 349 }
360 350
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 if (FLAG_gc_greedy) v8::internal::Heap::GarbageCollectionGreedyCheck() 384 if (FLAG_gc_greedy) v8::internal::Heap::GarbageCollectionGreedyCheck()
395 #else 385 #else
396 #define GC_GREEDY_CHECK() { } 386 #define GC_GREEDY_CHECK() { }
397 #endif 387 #endif
398 388
399 389
400 // Calls the FUNCTION_CALL function and retries it up to three times 390 // Calls the FUNCTION_CALL function and retries it up to three times
401 // to guarantee that any allocations performed during the call will 391 // to guarantee that any allocations performed during the call will
402 // succeed if there's enough memory. 392 // succeed if there's enough memory.
403 393
404 // Warning: Do not use the identifiers __object__ or __scope__ in a 394 // Warning: Do not use the identifiers __object__, __maybe_object__ or
405 // call to this macro. 395 // __scope__ in a call to this macro.
406 396
407 #define CALL_AND_RETRY(FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY) \ 397 #define CALL_AND_RETRY(FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY) \
408 do { \ 398 do { \
409 GC_GREEDY_CHECK(); \ 399 GC_GREEDY_CHECK(); \
410 Object* __object__ = FUNCTION_CALL; \ 400 MaybeObject* __maybe_object__ = FUNCTION_CALL; \
411 if (!__object__->IsFailure()) RETURN_VALUE; \ 401 Object* __object__ = NULL; \
412 if (__object__->IsOutOfMemoryFailure()) { \ 402 if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \
403 if (__maybe_object__->IsOutOfMemory()) { \
413 v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_0", true);\ 404 v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_0", true);\
414 } \ 405 } \
415 if (!__object__->IsRetryAfterGC()) RETURN_EMPTY; \ 406 if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \
416 Heap::CollectGarbage(Failure::cast(__object__)->allocation_space()); \ 407 Heap::CollectGarbage(Failure::cast(__maybe_object__)-> \
417 __object__ = FUNCTION_CALL; \ 408 allocation_space()); \
418 if (!__object__->IsFailure()) RETURN_VALUE; \ 409 __maybe_object__ = FUNCTION_CALL; \
419 if (__object__->IsOutOfMemoryFailure()) { \ 410 if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \
411 if (__maybe_object__->IsOutOfMemory()) { \
420 v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_1", true);\ 412 v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_1", true);\
421 } \ 413 } \
422 if (!__object__->IsRetryAfterGC()) RETURN_EMPTY; \ 414 if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \
423 Counters::gc_last_resort_from_handles.Increment(); \ 415 Counters::gc_last_resort_from_handles.Increment(); \
424 Heap::CollectAllAvailableGarbage(); \ 416 Heap::CollectAllGarbage(false); \
425 { \ 417 { \
426 AlwaysAllocateScope __scope__; \ 418 AlwaysAllocateScope __scope__; \
427 __object__ = FUNCTION_CALL; \ 419 __maybe_object__ = FUNCTION_CALL; \
428 } \ 420 } \
429 if (!__object__->IsFailure()) RETURN_VALUE; \ 421 if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \
430 if (__object__->IsOutOfMemoryFailure() || \ 422 if (__maybe_object__->IsOutOfMemory() || \
431 __object__->IsRetryAfterGC()) { \ 423 __maybe_object__->IsRetryAfterGC()) { \
432 /* TODO(1181417): Fix this. */ \ 424 /* TODO(1181417): Fix this. */ \
433 v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_2", true);\ 425 v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_2", true);\
434 } \ 426 } \
435 RETURN_EMPTY; \ 427 RETURN_EMPTY; \
436 } while (false) 428 } while (false)
437 429
438 430
439 #define CALL_HEAP_FUNCTION(FUNCTION_CALL, TYPE) \ 431 #define CALL_HEAP_FUNCTION(FUNCTION_CALL, TYPE) \
440 CALL_AND_RETRY(FUNCTION_CALL, \ 432 CALL_AND_RETRY(FUNCTION_CALL, \
441 return Handle<TYPE>(TYPE::cast(__object__)), \ 433 return Handle<TYPE>(TYPE::cast(__object__)), \
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 495
504 496
505 void ExternalStringTable::ShrinkNewStrings(int position) { 497 void ExternalStringTable::ShrinkNewStrings(int position) {
506 new_space_strings_.Rewind(position); 498 new_space_strings_.Rewind(position);
507 Verify(); 499 Verify();
508 } 500 }
509 501
510 } } // namespace v8::internal 502 } } // namespace v8::internal
511 503
512 #endif // V8_HEAP_INL_H_ 504 #endif // V8_HEAP_INL_H_
OLDNEW
« no previous file with comments | « src/heap.cc ('k') | src/ia32/assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698