00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef V8_HEAP_H_
00029 #define V8_HEAP_H_
00030
00031 namespace v8 { namespace internal {
00032
00033
00034 #define STRONG_ROOT_LIST(V) \
00035 V(Map, meta_map) \
00036 V(Map, heap_number_map) \
00037 V(Map, short_string_map) \
00038 V(Map, medium_string_map) \
00039 V(Map, long_string_map) \
00040 V(Map, short_ascii_string_map) \
00041 V(Map, medium_ascii_string_map) \
00042 V(Map, long_ascii_string_map) \
00043 V(Map, short_symbol_map) \
00044 V(Map, medium_symbol_map) \
00045 V(Map, long_symbol_map) \
00046 V(Map, short_ascii_symbol_map) \
00047 V(Map, medium_ascii_symbol_map) \
00048 V(Map, long_ascii_symbol_map) \
00049 V(Map, short_cons_symbol_map) \
00050 V(Map, medium_cons_symbol_map) \
00051 V(Map, long_cons_symbol_map) \
00052 V(Map, short_cons_ascii_symbol_map) \
00053 V(Map, medium_cons_ascii_symbol_map) \
00054 V(Map, long_cons_ascii_symbol_map) \
00055 V(Map, short_sliced_symbol_map) \
00056 V(Map, medium_sliced_symbol_map) \
00057 V(Map, long_sliced_symbol_map) \
00058 V(Map, short_sliced_ascii_symbol_map) \
00059 V(Map, medium_sliced_ascii_symbol_map) \
00060 V(Map, long_sliced_ascii_symbol_map) \
00061 V(Map, short_external_symbol_map) \
00062 V(Map, medium_external_symbol_map) \
00063 V(Map, long_external_symbol_map) \
00064 V(Map, short_external_ascii_symbol_map) \
00065 V(Map, medium_external_ascii_symbol_map) \
00066 V(Map, long_external_ascii_symbol_map) \
00067 V(Map, short_cons_string_map) \
00068 V(Map, medium_cons_string_map) \
00069 V(Map, long_cons_string_map) \
00070 V(Map, short_cons_ascii_string_map) \
00071 V(Map, medium_cons_ascii_string_map) \
00072 V(Map, long_cons_ascii_string_map) \
00073 V(Map, short_sliced_string_map) \
00074 V(Map, medium_sliced_string_map) \
00075 V(Map, long_sliced_string_map) \
00076 V(Map, short_sliced_ascii_string_map) \
00077 V(Map, medium_sliced_ascii_string_map) \
00078 V(Map, long_sliced_ascii_string_map) \
00079 V(Map, short_external_string_map) \
00080 V(Map, medium_external_string_map) \
00081 V(Map, long_external_string_map) \
00082 V(Map, short_external_ascii_string_map) \
00083 V(Map, medium_external_ascii_string_map) \
00084 V(Map, long_external_ascii_string_map) \
00085 V(Map, undetectable_short_string_map) \
00086 V(Map, undetectable_medium_string_map) \
00087 V(Map, undetectable_long_string_map) \
00088 V(Map, undetectable_short_ascii_string_map) \
00089 V(Map, undetectable_medium_ascii_string_map) \
00090 V(Map, undetectable_long_ascii_string_map) \
00091 V(Map, byte_array_map) \
00092 V(Map, fixed_array_map) \
00093 V(Map, hash_table_map) \
00094 V(Map, context_map) \
00095 V(Map, global_context_map) \
00096 V(Map, code_map) \
00097 V(Map, oddball_map) \
00098 V(Map, boilerplate_function_map) \
00099 V(Map, shared_function_info_map) \
00100 V(Map, proxy_map) \
00101 V(Map, one_word_filler_map) \
00102 V(Map, two_word_filler_map) \
00103 V(Object, nan_value) \
00104 V(Object, undefined_value) \
00105 V(Object, minus_zero_value) \
00106 V(Object, null_value) \
00107 V(Object, true_value) \
00108 V(Object, false_value) \
00109 V(String, empty_string) \
00110 V(FixedArray, empty_fixed_array) \
00111 V(DescriptorArray, empty_descriptor_array) \
00112 V(Object, the_hole_value) \
00113 V(Map, neander_map) \
00114 V(JSObject, message_listeners) \
00115 V(Proxy, prototype_accessors) \
00116 V(JSObject, debug_event_listeners) \
00117 V(Dictionary, code_stubs) \
00118 V(Dictionary, non_monomorphic_cache) \
00119 V(Code, js_entry_code) \
00120 V(Code, js_construct_entry_code) \
00121 V(Code, c_entry_code) \
00122 V(Code, c_entry_debug_break_code) \
00123 V(FixedArray, number_string_cache) \
00124 V(FixedArray, single_character_string_cache) \
00125 V(FixedArray, natives_source_cache) \
00126 V(Object, keyed_lookup_cache)
00127
00128
00129 #define ROOT_LIST(V) \
00130 STRONG_ROOT_LIST(V) \
00131 V(Object, symbol_table)
00132
00133 #define SYMBOL_LIST(V) \
00134 V(Array_symbol, "Array") \
00135 V(Object_symbol, "Object") \
00136 V(Proto_symbol, "__proto__") \
00137 V(StringImpl_symbol, "StringImpl") \
00138 V(arguments_symbol, "arguments") \
00139 V(Arguments_symbol, "Arguments") \
00140 V(arguments_shadow_symbol, ".arguments") \
00141 V(call_symbol, "call") \
00142 V(apply_symbol, "apply") \
00143 V(caller_symbol, "caller") \
00144 V(boolean_symbol, "boolean") \
00145 V(Boolean_symbol, "Boolean") \
00146 V(callee_symbol, "callee") \
00147 V(constructor_symbol, "constructor") \
00148 V(code_symbol, ".code") \
00149 V(result_symbol, ".result") \
00150 V(catch_var_symbol, ".catch-var") \
00151 V(empty_symbol, "") \
00152 V(eval_symbol, "eval") \
00153 V(function_symbol, "function") \
00154 V(length_symbol, "length") \
00155 V(name_symbol, "name") \
00156 V(number_symbol, "number") \
00157 V(Number_symbol, "Number") \
00158 V(RegExp_symbol, "RegExp") \
00159 V(object_symbol, "object") \
00160 V(prototype_symbol, "prototype") \
00161 V(string_symbol, "string") \
00162 V(String_symbol, "String") \
00163 V(Date_symbol, "Date") \
00164 V(this_symbol, "this") \
00165 V(to_string_symbol, "toString") \
00166 V(char_at_symbol, "CharAt") \
00167 V(undefined_symbol, "undefined") \
00168 V(value_of_symbol, "valueOf") \
00169 V(CreateObjectLiteralBoilerplate_symbol, "CreateObjectLiteralBoilerplate") \
00170 V(CreateArrayLiteral_symbol, "CreateArrayLiteral") \
00171 V(InitializeVarGlobal_symbol, "InitializeVarGlobal") \
00172 V(InitializeConstGlobal_symbol, "InitializeConstGlobal") \
00173 V(stack_overflow_symbol, "kStackOverflowBoilerplate") \
00174 V(illegal_access_symbol, "illegal access") \
00175 V(out_of_memory_symbol, "out-of-memory") \
00176 V(illegal_execution_state_symbol, "illegal execution state") \
00177 V(get_symbol, "get") \
00178 V(set_symbol, "set") \
00179 V(function_class_symbol, "Function") \
00180 V(illegal_argument_symbol, "illegal argument") \
00181 V(MakeReferenceError_symbol, "MakeReferenceError") \
00182 V(MakeSyntaxError_symbol, "MakeSyntaxError") \
00183 V(MakeTypeError_symbol, "MakeTypeError") \
00184 V(invalid_lhs_in_assignment_symbol, "invalid_lhs_in_assignment") \
00185 V(invalid_lhs_in_for_in_symbol, "invalid_lhs_in_for_in") \
00186 V(invalid_lhs_in_postfix_op_symbol, "invalid_lhs_in_postfix_op") \
00187 V(invalid_lhs_in_prefix_op_symbol, "invalid_lhs_in_prefix_op") \
00188 V(illegal_return_symbol, "illegal_return") \
00189 V(illegal_break_symbol, "illegal_break") \
00190 V(illegal_continue_symbol, "illegal_continue") \
00191 V(unknown_label_symbol, "unknown_label") \
00192 V(redeclaration_symbol, "redeclaration") \
00193 V(failure_symbol, "<failure>") \
00194 V(space_symbol, " ") \
00195 V(exec_symbol, "exec") \
00196 V(zero_symbol, "0")
00197
00198
00199
00200 class GCTracer;
00201
00202
00203
00204
00205
00206 class Heap : public AllStatic {
00207 public:
00208
00209
00210 static bool ConfigureHeap(int semispace_size, int old_gen_size);
00211 static bool ConfigureHeapDefault();
00212
00213
00214
00215
00216 static bool Setup(bool create_heap_objects);
00217
00218
00219 static void TearDown();
00220
00221
00222 static bool HasBeenSetup();
00223
00224
00225 static int MaxCapacity() {
00226 return young_generation_size_ + old_generation_size_;
00227 }
00228 static int SemiSpaceSize() { return semispace_size_; }
00229 static int InitialSemiSpaceSize() { return initial_semispace_size_; }
00230 static int YoungGenerationSize() { return young_generation_size_; }
00231 static int OldGenerationSize() { return old_generation_size_; }
00232
00233
00234
00235 static int Capacity();
00236
00237
00238
00239
00240 static int Available();
00241
00242
00243
00244 static inline int MaxHeapObjectSize();
00245
00246
00247 static int SizeOfObjects();
00248
00249
00250
00251
00252 static Address NewSpaceStart() { return new_space_.start(); }
00253 static uint32_t NewSpaceMask() { return new_space_.mask(); }
00254 static Address NewSpaceTop() { return new_space_.top(); }
00255
00256 static NewSpace* new_space() { return &new_space_; }
00257 static OldSpace* old_pointer_space() { return old_pointer_space_; }
00258 static OldSpace* old_data_space() { return old_data_space_; }
00259 static OldSpace* code_space() { return code_space_; }
00260 static MapSpace* map_space() { return map_space_; }
00261 static LargeObjectSpace* lo_space() { return lo_space_; }
00262
00263 static bool always_allocate() { return always_allocate_scope_depth_ != 0; }
00264 static Address always_allocate_scope_depth_address() {
00265 return reinterpret_cast<Address>(&always_allocate_scope_depth_);
00266 }
00267
00268 static Address* NewSpaceAllocationTopAddress() {
00269 return new_space_.allocation_top_address();
00270 }
00271 static Address* NewSpaceAllocationLimitAddress() {
00272 return new_space_.allocation_limit_address();
00273 }
00274
00275
00276
00277
00278
00279
00280 static Object* AllocateJSObject(JSFunction* constructor,
00281 PretenureFlag pretenure = NOT_TENURED);
00282
00283
00284
00285
00286 static Object* CopyJSObject(JSObject* source);
00287
00288
00289
00290
00291
00292 static Object* AllocateFunctionPrototype(JSFunction* function);
00293
00294
00295
00296
00297
00298 static Object* ReinitializeJSGlobalProxy(JSFunction* constructor,
00299 JSGlobalProxy* global);
00300
00301
00302
00303
00304
00305 static Object* AllocateJSObjectFromMap(Map* map,
00306 PretenureFlag pretenure = NOT_TENURED);
00307
00308
00309
00310
00311
00312 static Object* Allocate(Map* map, AllocationSpace space);
00313
00314
00315
00316
00317
00318 static Object* AllocateMap(InstanceType instance_type, int instance_size);
00319
00320
00321 static Object* AllocatePartialMap(InstanceType instance_type,
00322 int instance_size);
00323
00324
00325 static Object* AllocateInitialMap(JSFunction* fun);
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 static Object* AllocateStringFromAscii(
00346 Vector<const char> str,
00347 PretenureFlag pretenure = NOT_TENURED);
00348 static Object* AllocateStringFromUtf8(
00349 Vector<const char> str,
00350 PretenureFlag pretenure = NOT_TENURED);
00351 static Object* AllocateStringFromTwoByte(
00352 Vector<const uc16> str,
00353 PretenureFlag pretenure = NOT_TENURED);
00354
00355
00356
00357
00358
00359 static Object* AllocateSymbol(unibrow::CharacterStream* buffer,
00360 int chars,
00361 uint32_t length_field);
00362
00363
00364
00365
00366
00367
00368
00369
00370 static Object* AllocateRawAsciiString(
00371 int length,
00372 PretenureFlag pretenure = NOT_TENURED);
00373 static Object* AllocateRawTwoByteString(
00374 int length,
00375 PretenureFlag pretenure = NOT_TENURED);
00376
00377
00378
00379
00380
00381 static Object* LookupSingleCharacterStringFromCode(uint16_t code);
00382
00383
00384
00385
00386
00387 static Object* AllocateByteArray(int length);
00388
00389
00390
00391
00392
00393 static Object* AllocateFixedArray(int length, PretenureFlag pretenure);
00394
00395 static Object* AllocateFixedArray(int length);
00396
00397
00398
00399 static Object* CopyFixedArray(FixedArray* src);
00400
00401
00402
00403
00404
00405 static Object* AllocateFixedArrayWithHoles(int length);
00406
00407
00408
00409 static Object* AllocateHashTable(int length);
00410
00411
00412 static Object* AllocateGlobalContext();
00413
00414
00415 static Object* AllocateFunctionContext(int length, JSFunction* closure);
00416
00417
00418 static Object* AllocateWithContext(Context* previous, JSObject* extension);
00419
00420
00421 static Object* AllocateStruct(InstanceType type);
00422
00423
00424
00425
00426
00427
00428
00429
00430 static Object* InitializeFunction(JSFunction* function,
00431 SharedFunctionInfo* shared,
00432 Object* prototype);
00433
00434
00435
00436
00437
00438 static Object* AllocateFunction(Map* function_map,
00439 SharedFunctionInfo* shared,
00440 Object* prototype);
00441
00442
00443 static const int arguments_callee_index = 0;
00444 static const int arguments_length_index = 1;
00445
00446
00447
00448
00449
00450 static Object* AllocateArgumentsObject(Object* callee, int length);
00451
00452
00453
00454
00455
00456 static Object* NewNumberFromDouble(double value,
00457 PretenureFlag pretenure = NOT_TENURED);
00458
00459
00460
00461 static Object* NumberFromDouble(double value,
00462 PretenureFlag pretenure = NOT_TENURED);
00463
00464
00465 static Object* AllocateHeapNumber(double value, PretenureFlag pretenure);
00466 static Object* AllocateHeapNumber(double value);
00467
00468
00469
00470
00471
00472 static inline Object* NumberFromInt32(int32_t value);
00473
00474
00475
00476
00477
00478 static inline Object* NumberFromUint32(uint32_t value);
00479
00480
00481
00482
00483
00484 static Object* AllocateProxy(Address proxy,
00485 PretenureFlag pretenure = NOT_TENURED);
00486
00487
00488
00489
00490
00491 static Object* AllocateSharedFunctionInfo(Object* name);
00492
00493
00494
00495
00496
00497 static Object* AllocateConsString(String* first, String* second);
00498
00499
00500
00501
00502
00503
00504
00505 static Object* AllocateSlicedString(String* buffer, int start, int end);
00506
00507
00508
00509
00510
00511
00512
00513 static Object* AllocateSubString(String* buffer, int start, int end);
00514
00515
00516
00517
00518
00519
00520 static Object* AllocateExternalStringFromAscii(
00521 ExternalAsciiString::Resource* resource);
00522 static Object* AllocateExternalStringFromTwoByte(
00523 ExternalTwoByteString::Resource* resource);
00524
00525
00526
00527
00528
00529
00530 static inline Object* AllocateRaw(int size_in_bytes,
00531 AllocationSpace space,
00532 AllocationSpace retry_space);
00533
00534
00535
00536
00537
00538 static Object* CreateCode(const CodeDesc& desc,
00539 ScopeInfo<>* sinfo,
00540 Code::Flags flags);
00541
00542 static Object* CopyCode(Code* code);
00543
00544
00545
00546
00547
00548 static Object* LookupSymbol(Vector<const char> str);
00549 static Object* LookupAsciiSymbol(const char* str) {
00550 return LookupSymbol(CStrVector(str));
00551 }
00552 static Object* LookupSymbol(String* str);
00553 static bool LookupSymbolIfExists(String* str, String** symbol);
00554
00555
00556
00557 static Map* SymbolMapForString(String* str);
00558
00559
00560 static Object* ToBoolean(bool condition) {
00561 return condition ? true_value() : false_value();
00562 }
00563
00564
00565
00566 static void GarbageCollectionPrologue();
00567 static void GarbageCollectionEpilogue();
00568
00569
00570
00571 static bool CollectGarbage(int required_space, AllocationSpace space);
00572
00573
00574 static void CollectAllGarbage();
00575
00576
00577
00578 static void PerformScavenge();
00579
00580 #ifdef DEBUG
00581
00582 static bool GarbageCollectionGreedyCheck();
00583 #endif
00584
00585 static void SetGlobalGCPrologueCallback(GCCallback callback) {
00586 global_gc_prologue_callback_ = callback;
00587 }
00588 static void SetGlobalGCEpilogueCallback(GCCallback callback) {
00589 global_gc_epilogue_callback_ = callback;
00590 }
00591
00592
00593 #define ROOT_ACCESSOR(type, name) static type* name() { return name##_; }
00594 ROOT_LIST(ROOT_ACCESSOR)
00595 #undef ROOT_ACCESSOR
00596
00597
00598 #define STRUCT_MAP_ACCESSOR(NAME, Name, name) \
00599 static Map* name##_map() { return name##_map_; }
00600 STRUCT_LIST(STRUCT_MAP_ACCESSOR)
00601 #undef STRUCT_MAP_ACCESSOR
00602
00603 #define SYMBOL_ACCESSOR(name, str) static String* name() { return name##_; }
00604 SYMBOL_LIST(SYMBOL_ACCESSOR)
00605 #undef SYMBOL_ACCESSOR
00606
00607
00608 static void IterateRoots(ObjectVisitor* v);
00609
00610 static void IterateStrongRoots(ObjectVisitor* v);
00611
00612
00613 static void IterateRSet(PagedSpace* space, ObjectSlotCallback callback);
00614
00615
00616
00617
00618 static void IterateRSetRange(Address object_start,
00619 Address object_end,
00620 Address rset_start,
00621 ObjectSlotCallback copy_object_func);
00622
00623
00624 static inline bool InNewSpace(Object* object);
00625 static inline bool InFromSpace(Object* object);
00626 static inline bool InToSpace(Object* object);
00627
00628
00629
00630 static bool Contains(Address addr);
00631 static bool Contains(HeapObject* value);
00632
00633
00634
00635 static bool InSpace(Address addr, AllocationSpace space);
00636 static bool InSpace(HeapObject* value, AllocationSpace space);
00637
00638
00639 static inline OldSpace* TargetSpace(HeapObject* object);
00640 static inline AllocationSpace TargetSpaceId(InstanceType type);
00641
00642
00643 static void set_code_stubs(Dictionary* value) { code_stubs_ = value; }
00644
00645
00646 static void set_non_monomorphic_cache(Dictionary* value) {
00647 non_monomorphic_cache_ = value;
00648 }
00649
00650
00651 static inline Object* GetKeyedLookupCache();
00652 static inline void SetKeyedLookupCache(LookupCache* cache);
00653 static inline void ClearKeyedLookupCache();
00654
00655 #ifdef DEBUG
00656 static void Print();
00657 static void PrintHandles();
00658
00659
00660 static void Verify();
00661
00662
00663 static void ReportHeapStatistics(const char* title);
00664 static void ReportCodeStatistics(const char* title);
00665
00666
00667 static void ZapFromSpace();
00668 #endif
00669
00670
00671
00672
00673
00674 static Object* CreateSymbol(const char* str, int length, int hash);
00675 static Object* CreateSymbol(String* str);
00676
00677
00678 inline static void RecordWrite(Address address, int offset);
00679
00680
00681 static Object* FindCodeObject(Address a);
00682
00683
00684 static void Shrink();
00685
00686 enum HeapState { NOT_IN_GC, SCAVENGE, MARK_COMPACT };
00687 static inline HeapState gc_state() { return gc_state_; }
00688
00689 #ifdef DEBUG
00690 static bool IsAllocationAllowed() { return allocation_allowed_; }
00691 static inline bool allow_allocation(bool enable);
00692
00693 static bool disallow_allocation_failure() {
00694 return disallow_allocation_failure_;
00695 }
00696
00697 static void TracePathToObject();
00698 static void TracePathToGlobal();
00699 #endif
00700
00701
00702
00703
00704
00705 static void ScavengePointer(HeapObject** p);
00706 static inline void ScavengeObject(HeapObject** p, HeapObject* object);
00707
00708
00709
00710
00711 static void ClearRSetRange(Address start, int size_in_bytes);
00712
00713
00714 static void RebuildRSets();
00715
00716
00717
00718
00719
00720 static bool CreateApiObjects();
00721
00722
00723
00724 static Object* GetNumberStringCache(Object* number);
00725
00726
00727 static void SetNumberStringCache(Object* number, String* str);
00728
00729
00730 static const int kNumberStringCacheSize = 64;
00731
00732
00733
00734 static int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
00735 int amount = amount_of_external_allocated_memory_ + change_in_bytes;
00736 if (change_in_bytes >= 0) {
00737
00738 if (amount > amount_of_external_allocated_memory_) {
00739 amount_of_external_allocated_memory_ = amount;
00740 }
00741 } else {
00742
00743 if (amount >= 0) {
00744 amount_of_external_allocated_memory_ = amount;
00745 }
00746 }
00747 ASSERT(amount_of_external_allocated_memory_ >= 0);
00748 return amount_of_external_allocated_memory_;
00749 }
00750
00751
00752 static Object* AllocateRawFixedArray(int length);
00753
00754
00755
00756 static bool OldGenerationPromotionLimitReached() {
00757 return (PromotedSpaceSize() + PromotedExternalMemorySize())
00758 > old_gen_promotion_limit_;
00759 }
00760
00761
00762
00763 static bool OldGenerationAllocationLimitReached() {
00764 return (PromotedSpaceSize() + PromotedExternalMemorySize())
00765 > old_gen_allocation_limit_;
00766 }
00767
00768 private:
00769 static int semispace_size_;
00770 static int initial_semispace_size_;
00771 static int young_generation_size_;
00772 static int old_generation_size_;
00773
00774 static int new_space_growth_limit_;
00775 static int scavenge_count_;
00776
00777 static int always_allocate_scope_depth_;
00778
00779 static const int kMaxMapSpaceSize = 8*MB;
00780
00781 static NewSpace new_space_;
00782 static OldSpace* old_pointer_space_;
00783 static OldSpace* old_data_space_;
00784 static OldSpace* code_space_;
00785 static MapSpace* map_space_;
00786 static LargeObjectSpace* lo_space_;
00787 static HeapState gc_state_;
00788
00789
00790 static int PromotedSpaceSize();
00791
00792
00793 static int PromotedExternalMemorySize();
00794
00795 static int mc_count_;
00796 static int gc_count_;
00797
00798 #ifdef DEBUG
00799 static bool allocation_allowed_;
00800
00801
00802
00803
00804 static int allocation_timeout_;
00805
00806
00807
00808 static bool disallow_allocation_failure_;
00809 #endif // DEBUG
00810
00811
00812
00813
00814 static int old_gen_promotion_limit_;
00815
00816
00817
00818
00819 static int old_gen_allocation_limit_;
00820
00821
00822
00823 static int amount_of_external_allocated_memory_;
00824
00825
00826 static int amount_of_external_allocated_memory_at_last_global_gc_;
00827
00828
00829
00830 static int old_gen_exhausted_;
00831
00832
00833 #define ROOT_DECLARATION(type, name) static type* name##_;
00834 ROOT_LIST(ROOT_DECLARATION)
00835 #undef ROOT_DECLARATION
00836
00837
00838 #define DECLARE_STRUCT_MAP(NAME, Name, name) static Map* name##_map_;
00839 STRUCT_LIST(DECLARE_STRUCT_MAP)
00840 #undef DECLARE_STRUCT_MAP
00841
00842 #define SYMBOL_DECLARATION(name, str) static String* name##_;
00843 SYMBOL_LIST(SYMBOL_DECLARATION)
00844 #undef SYMBOL_DECLARATION
00845
00846
00847
00848 static GCCallback global_gc_prologue_callback_;
00849 static GCCallback global_gc_epilogue_callback_;
00850
00851
00852 static GarbageCollector SelectGarbageCollector(AllocationSpace space);
00853
00854
00855 static void PerformGarbageCollection(AllocationSpace space,
00856 GarbageCollector collector,
00857 GCTracer* tracer);
00858
00859
00860
00861 static Object* SmiOrNumberFromDouble(double value,
00862 bool new_object,
00863 PretenureFlag pretenure = NOT_TENURED);
00864
00865
00866
00867
00868
00869 static inline Object* AllocateRawMap(int size_in_bytes);
00870
00871
00872 static void InitializeJSObjectFromMap(JSObject* obj,
00873 FixedArray* properties,
00874 Map* map);
00875
00876 static bool CreateInitialMaps();
00877 static bool CreateInitialObjects();
00878 static void CreateFixedStubs();
00879 static Object* CreateOddball(Map* map,
00880 const char* to_string,
00881 Object* to_number);
00882
00883
00884 static Object* AllocateEmptyFixedArray();
00885
00886
00887 static void Scavenge();
00888
00889
00890 static void MarkCompact(GCTracer* tracer);
00891
00892
00893 static void MarkCompactPrologue();
00894 static void MarkCompactEpilogue();
00895
00896
00897
00898
00899 static HeapObject* MigrateObject(HeapObject* source,
00900 HeapObject* target,
00901 int size);
00902
00903
00904
00905
00906
00907 static inline bool ShouldBePromoted(Address old_address, int object_size);
00908 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
00909
00910 static void RecordCopiedObject(HeapObject* obj);
00911
00912
00913 static void ReportStatisticsBeforeGC();
00914 static void ReportStatisticsAfterGC();
00915 #endif
00916
00917
00918 static int UpdateRSet(HeapObject* obj);
00919
00920
00921 static void RebuildRSets(PagedSpace* space);
00922
00923
00924 static void RebuildRSets(LargeObjectSpace* space);
00925
00926
00927 static void ScavengeObjectSlow(HeapObject** p, HeapObject* object);
00928
00929
00930 inline static void CopyBlock(Object** dst, Object** src, int byte_size);
00931
00932 static const int kInitialSymbolTableSize = 2048;
00933 static const int kInitialEvalCacheSize = 64;
00934
00935 friend class Factory;
00936 friend class DisallowAllocationFailure;
00937 friend class AlwaysAllocateScope;
00938 };
00939
00940
00941 class AlwaysAllocateScope {
00942 public:
00943 AlwaysAllocateScope() {
00944
00945
00946
00947
00948 ASSERT(Heap::always_allocate_scope_depth_ == 0);
00949 Heap::always_allocate_scope_depth_++;
00950 }
00951
00952 ~AlwaysAllocateScope() {
00953 Heap::always_allocate_scope_depth_--;
00954 ASSERT(Heap::always_allocate_scope_depth_ == 0);
00955 }
00956 };
00957
00958
00959 #ifdef DEBUG
00960
00961
00962
00963
00964
00965 class VerifyPointersVisitor: public ObjectVisitor {
00966 public:
00967 void VisitPointers(Object** start, Object** end) {
00968 for (Object** current = start; current < end; current++) {
00969 if ((*current)->IsHeapObject()) {
00970 HeapObject* object = HeapObject::cast(*current);
00971 ASSERT(Heap::Contains(object));
00972 ASSERT(object->map()->IsMap());
00973 }
00974 }
00975 }
00976 };
00977
00978
00979
00980
00981
00982 class VerifyPointersAndRSetVisitor: public ObjectVisitor {
00983 public:
00984 void VisitPointers(Object** start, Object** end) {
00985 for (Object** current = start; current < end; current++) {
00986 if ((*current)->IsHeapObject()) {
00987 HeapObject* object = HeapObject::cast(*current);
00988 ASSERT(Heap::Contains(object));
00989 ASSERT(object->map()->IsMap());
00990 if (Heap::InNewSpace(object)) {
00991 ASSERT(Page::IsRSetSet(reinterpret_cast<Address>(current), 0));
00992 }
00993 }
00994 }
00995 }
00996 };
00997 #endif
00998
00999
01000
01001
01002 class AllSpaces BASE_EMBEDDED {
01003 public:
01004 Space* next();
01005 AllSpaces() { counter_ = FIRST_SPACE; }
01006 private:
01007 int counter_;
01008 };
01009
01010
01011
01012
01013
01014 class OldSpaces BASE_EMBEDDED {
01015 public:
01016 OldSpace* next();
01017 OldSpaces() { counter_ = OLD_POINTER_SPACE; }
01018 private:
01019 int counter_;
01020 };
01021
01022
01023
01024
01025
01026 class PagedSpaces BASE_EMBEDDED {
01027 public:
01028 PagedSpace* next();
01029 PagedSpaces() { counter_ = OLD_POINTER_SPACE; }
01030 private:
01031 int counter_;
01032 };
01033
01034
01035
01036
01037
01038 class SpaceIterator : public Malloced {
01039 public:
01040 SpaceIterator();
01041 virtual ~SpaceIterator();
01042
01043 bool has_next();
01044 ObjectIterator* next();
01045
01046 private:
01047 ObjectIterator* CreateIterator();
01048
01049 int current_space_;
01050 ObjectIterator* iterator_;
01051 };
01052
01053
01054
01055
01056
01057
01058 class HeapIterator BASE_EMBEDDED {
01059 public:
01060 explicit HeapIterator();
01061 virtual ~HeapIterator();
01062
01063 bool has_next();
01064 HeapObject* next();
01065 void reset();
01066
01067 private:
01068
01069 void Init();
01070
01071
01072 void Shutdown();
01073
01074
01075 SpaceIterator* space_iterator_;
01076
01077 ObjectIterator* object_iterator_;
01078 };
01079
01080
01081
01082
01083
01084 class MarkingStack {
01085 public:
01086 void Initialize(Address low, Address high) {
01087 top_ = low_ = reinterpret_cast<HeapObject**>(low);
01088 high_ = reinterpret_cast<HeapObject**>(high);
01089 overflowed_ = false;
01090 }
01091
01092 bool is_full() { return top_ >= high_; }
01093
01094 bool is_empty() { return top_ <= low_; }
01095
01096 bool overflowed() { return overflowed_; }
01097
01098 void clear_overflowed() { overflowed_ = false; }
01099
01100
01101
01102
01103 void Push(HeapObject* object) {
01104 CHECK(object->IsHeapObject());
01105 if (is_full()) {
01106 object->SetOverflow();
01107 overflowed_ = true;
01108 } else {
01109 *(top_++) = object;
01110 }
01111 }
01112
01113 HeapObject* Pop() {
01114 ASSERT(!is_empty());
01115 HeapObject* object = *(--top_);
01116 CHECK(object->IsHeapObject());
01117 return object;
01118 }
01119
01120 private:
01121 HeapObject** low_;
01122 HeapObject** top_;
01123 HeapObject** high_;
01124 bool overflowed_;
01125 };
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136 #ifdef DEBUG
01137
01138 class DisallowAllocationFailure {
01139 public:
01140 DisallowAllocationFailure() {
01141 old_state_ = Heap::disallow_allocation_failure_;
01142 Heap::disallow_allocation_failure_ = true;
01143 }
01144 ~DisallowAllocationFailure() {
01145 Heap::disallow_allocation_failure_ = old_state_;
01146 }
01147 private:
01148 bool old_state_;
01149 };
01150
01151 class AssertNoAllocation {
01152 public:
01153 AssertNoAllocation() {
01154 old_state_ = Heap::allow_allocation(false);
01155 }
01156
01157 ~AssertNoAllocation() {
01158 Heap::allow_allocation(old_state_);
01159 }
01160
01161 private:
01162 bool old_state_;
01163 };
01164
01165 #else // ndef DEBUG
01166
01167 class AssertNoAllocation {
01168 public:
01169 AssertNoAllocation() { }
01170 ~AssertNoAllocation() { }
01171 };
01172
01173 #endif
01174
01175 #ifdef ENABLE_LOGGING_AND_PROFILING
01176
01177
01178 class HeapProfiler {
01179 public:
01180
01181 static void WriteSample();
01182
01183 private:
01184
01185 static void CollectStats(HeapObject* obj, HistogramInfo* info);
01186 };
01187 #endif
01188
01189
01190
01191
01192 class GCTracer BASE_EMBEDDED {
01193 public:
01194 GCTracer();
01195
01196 ~GCTracer();
01197
01198
01199 void set_collector(GarbageCollector collector) { collector_ = collector; }
01200
01201
01202 void set_gc_count(int count) { gc_count_ = count; }
01203
01204
01205 void set_full_gc_count(int count) { full_gc_count_ = count; }
01206
01207
01208 void set_is_compacting() { is_compacting_ = true; }
01209
01210
01211 void increment_marked_count() { ++marked_count_; }
01212 void decrement_marked_count() { --marked_count_; }
01213
01214 int marked_count() { return marked_count_; }
01215
01216 private:
01217
01218 const char* CollectorString();
01219
01220
01221 double SizeOfHeapObjects() {
01222 return (static_cast<double>(Heap::SizeOfObjects())) / MB;
01223 }
01224
01225 double start_time_;
01226 double start_size_;
01227 GarbageCollector collector_;
01228
01229
01230
01231 int gc_count_;
01232
01233
01234 int full_gc_count_;
01235
01236
01237
01238 bool is_compacting_;
01239
01240
01241
01242 bool previous_has_compacted_;
01243
01244
01245
01246
01247 int marked_count_;
01248
01249
01250
01251 int previous_marked_count_;
01252 };
01253
01254 } }
01255
01256 #endif // V8_HEAP_H_