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

Side by Side Diff: src/heap.cc

Issue 112863002: Merge bleeding_edge 18021:18297 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years 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.h ('k') | src/heap-inl.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 // 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 // Will be 4 * reserved_semispace_size_ to ensure that young 80 // Will be 4 * reserved_semispace_size_ to ensure that young
81 // generation can be aligned to its size. 81 // generation can be aligned to its size.
82 maximum_committed_(0), 82 maximum_committed_(0),
83 survived_since_last_expansion_(0), 83 survived_since_last_expansion_(0),
84 sweep_generation_(0), 84 sweep_generation_(0),
85 always_allocate_scope_depth_(0), 85 always_allocate_scope_depth_(0),
86 linear_allocation_scope_depth_(0), 86 linear_allocation_scope_depth_(0),
87 contexts_disposed_(0), 87 contexts_disposed_(0),
88 global_ic_age_(0), 88 global_ic_age_(0),
89 flush_monomorphic_ics_(false), 89 flush_monomorphic_ics_(false),
90 allocation_mementos_found_(0),
91 scan_on_scavenge_pages_(0), 90 scan_on_scavenge_pages_(0),
92 new_space_(this), 91 new_space_(this),
93 old_pointer_space_(NULL), 92 old_pointer_space_(NULL),
94 old_data_space_(NULL), 93 old_data_space_(NULL),
95 code_space_(NULL), 94 code_space_(NULL),
96 map_space_(NULL), 95 map_space_(NULL),
97 cell_space_(NULL), 96 cell_space_(NULL),
98 property_cell_space_(NULL), 97 property_cell_space_(NULL),
99 lo_space_(NULL), 98 lo_space_(NULL),
100 gc_state_(NOT_IN_GC), 99 gc_state_(NOT_IN_GC),
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 PagedSpaces spaces(this); 498 PagedSpaces spaces(this);
500 for (PagedSpace* space = spaces.next(); 499 for (PagedSpace* space = spaces.next();
501 space != NULL; 500 space != NULL;
502 space = spaces.next()) { 501 space = spaces.next()) {
503 space->RepairFreeListsAfterBoot(); 502 space->RepairFreeListsAfterBoot();
504 } 503 }
505 } 504 }
506 505
507 506
508 void Heap::GarbageCollectionEpilogue() { 507 void Heap::GarbageCollectionEpilogue() {
508 if (FLAG_allocation_site_pretenuring) {
509 int tenure_decisions = 0;
510 int dont_tenure_decisions = 0;
511 int allocation_mementos_found = 0;
512
513 Object* cur = allocation_sites_list();
514 while (cur->IsAllocationSite()) {
515 AllocationSite* casted = AllocationSite::cast(cur);
516 allocation_mementos_found += casted->memento_found_count()->value();
517 if (casted->DigestPretenuringFeedback()) {
518 if (casted->GetPretenureMode() == TENURED) {
519 tenure_decisions++;
520 } else {
521 dont_tenure_decisions++;
522 }
523 }
524 cur = casted->weak_next();
525 }
526
527 // TODO(mvstanton): Pretenure decisions are only made once for an allocation
528 // site. Find a sane way to decide about revisiting the decision later.
529
530 if (FLAG_trace_track_allocation_sites &&
531 (allocation_mementos_found > 0 ||
532 tenure_decisions > 0 ||
533 dont_tenure_decisions > 0)) {
534 PrintF("GC: (#mementos, #tenure decisions, #donttenure decisions) "
535 "(%d, %d, %d)\n",
536 allocation_mementos_found,
537 tenure_decisions,
538 dont_tenure_decisions);
539 }
540 }
541
509 store_buffer()->GCEpilogue(); 542 store_buffer()->GCEpilogue();
510 543
511 // In release mode, we only zap the from space under heap verification. 544 // In release mode, we only zap the from space under heap verification.
512 if (Heap::ShouldZapGarbage()) { 545 if (Heap::ShouldZapGarbage()) {
513 ZapFromSpace(); 546 ZapFromSpace();
514 } 547 }
515 548
516 #ifdef VERIFY_HEAP 549 #ifdef VERIFY_HEAP
517 if (FLAG_verify_heap) { 550 if (FLAG_verify_heap) {
518 Verify(); 551 Verify();
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 } 1419 }
1387 1420
1388 private: 1421 private:
1389 Heap* heap_; 1422 Heap* heap_;
1390 }; 1423 };
1391 1424
1392 1425
1393 void Heap::Scavenge() { 1426 void Heap::Scavenge() {
1394 RelocationLock relocation_lock(this); 1427 RelocationLock relocation_lock(this);
1395 1428
1396 allocation_mementos_found_ = 0;
1397
1398 #ifdef VERIFY_HEAP 1429 #ifdef VERIFY_HEAP
1399 if (FLAG_verify_heap) VerifyNonPointerSpacePointers(this); 1430 if (FLAG_verify_heap) VerifyNonPointerSpacePointers(this);
1400 #endif 1431 #endif
1401 1432
1402 gc_state_ = SCAVENGE; 1433 gc_state_ = SCAVENGE;
1403 1434
1404 // Implements Cheney's copying algorithm 1435 // Implements Cheney's copying algorithm
1405 LOG(isolate_, ResourceEvent("scavenge", "begin")); 1436 LOG(isolate_, ResourceEvent("scavenge", "begin"));
1406 1437
1407 // Clear descriptor cache. 1438 // Clear descriptor cache.
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 &IsUnscavengedHeapObject); 1541 &IsUnscavengedHeapObject);
1511 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( 1542 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots(
1512 &scavenge_visitor); 1543 &scavenge_visitor);
1513 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); 1544 new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1514 1545
1515 UpdateNewSpaceReferencesInExternalStringTable( 1546 UpdateNewSpaceReferencesInExternalStringTable(
1516 &UpdateNewSpaceReferenceInExternalStringTableEntry); 1547 &UpdateNewSpaceReferenceInExternalStringTableEntry);
1517 1548
1518 promotion_queue_.Destroy(); 1549 promotion_queue_.Destroy();
1519 1550
1520 if (!FLAG_watch_ic_patching) {
1521 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge();
1522 }
1523 incremental_marking()->UpdateMarkingDequeAfterScavenge(); 1551 incremental_marking()->UpdateMarkingDequeAfterScavenge();
1524 1552
1525 ScavengeWeakObjectRetainer weak_object_retainer(this); 1553 ScavengeWeakObjectRetainer weak_object_retainer(this);
1526 ProcessWeakReferences(&weak_object_retainer); 1554 ProcessWeakReferences(&weak_object_retainer);
1527 1555
1528 ASSERT(new_space_front == new_space_.top()); 1556 ASSERT(new_space_front == new_space_.top());
1529 1557
1530 // Set age mark. 1558 // Set age mark.
1531 new_space_.set_age_mark(new_space_.top()); 1559 new_space_.set_age_mark(new_space_.top());
1532 1560
1533 new_space_.LowerInlineAllocationLimit( 1561 new_space_.LowerInlineAllocationLimit(
1534 new_space_.inline_allocation_limit_step()); 1562 new_space_.inline_allocation_limit_step());
1535 1563
1536 // Update how much has survived scavenge. 1564 // Update how much has survived scavenge.
1537 IncrementYoungSurvivorsCounter(static_cast<int>( 1565 IncrementYoungSurvivorsCounter(static_cast<int>(
1538 (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size())); 1566 (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size()));
1539 1567
1540 LOG(isolate_, ResourceEvent("scavenge", "end")); 1568 LOG(isolate_, ResourceEvent("scavenge", "end"));
1541 1569
1542 gc_state_ = NOT_IN_GC; 1570 gc_state_ = NOT_IN_GC;
1543 1571
1544 scavenges_since_last_idle_round_++; 1572 scavenges_since_last_idle_round_++;
1545
1546 if (FLAG_trace_track_allocation_sites && allocation_mementos_found_ > 0) {
1547 PrintF("AllocationMementos found during scavenge = %d\n",
1548 allocation_mementos_found_);
1549 }
1550 } 1573 }
1551 1574
1552 1575
1553 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, 1576 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
1554 Object** p) { 1577 Object** p) {
1555 MapWord first_word = HeapObject::cast(*p)->map_word(); 1578 MapWord first_word = HeapObject::cast(*p)->map_word();
1556 1579
1557 if (!first_word.IsForwardingAddress()) { 1580 if (!first_word.IsForwardingAddress()) {
1558 // Unreachable external string can be finalized. 1581 // Unreachable external string can be finalized.
1559 heap->FinalizeExternalString(String::cast(*p)); 1582 heap->FinalizeExternalString(String::cast(*p));
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
1908 Object* allocation_site_obj = 1931 Object* allocation_site_obj =
1909 VisitWeakList<AllocationSite>(this, 1932 VisitWeakList<AllocationSite>(this,
1910 allocation_sites_list(), 1933 allocation_sites_list(),
1911 retainer, record_slots); 1934 retainer, record_slots);
1912 set_allocation_sites_list(allocation_site_obj); 1935 set_allocation_sites_list(allocation_site_obj);
1913 } 1936 }
1914 1937
1915 1938
1916 void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) { 1939 void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) {
1917 DisallowHeapAllocation no_allocation; 1940 DisallowHeapAllocation no_allocation;
1918 1941 // All external strings are listed in the external string table.
1919 // Both the external string table and the string table may contain
1920 // external strings, but neither lists them exhaustively, nor is the
1921 // intersection set empty. Therefore we iterate over the external string
1922 // table first, ignoring internalized strings, and then over the
1923 // internalized string table.
1924 1942
1925 class ExternalStringTableVisitorAdapter : public ObjectVisitor { 1943 class ExternalStringTableVisitorAdapter : public ObjectVisitor {
1926 public: 1944 public:
1927 explicit ExternalStringTableVisitorAdapter( 1945 explicit ExternalStringTableVisitorAdapter(
1928 v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {} 1946 v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {}
1929 virtual void VisitPointers(Object** start, Object** end) { 1947 virtual void VisitPointers(Object** start, Object** end) {
1930 for (Object** p = start; p < end; p++) { 1948 for (Object** p = start; p < end; p++) {
1931 // Visit non-internalized external strings, 1949 ASSERT((*p)->IsExternalString());
1932 // since internalized strings are listed in the string table. 1950 visitor_->VisitExternalString(Utils::ToLocal(
1933 if (!(*p)->IsInternalizedString()) { 1951 Handle<String>(String::cast(*p))));
1934 ASSERT((*p)->IsExternalString());
1935 visitor_->VisitExternalString(Utils::ToLocal(
1936 Handle<String>(String::cast(*p))));
1937 }
1938 } 1952 }
1939 } 1953 }
1940 private: 1954 private:
1941 v8::ExternalResourceVisitor* visitor_; 1955 v8::ExternalResourceVisitor* visitor_;
1942 } external_string_table_visitor(visitor); 1956 } external_string_table_visitor(visitor);
1943 1957
1944 external_string_table_.Iterate(&external_string_table_visitor); 1958 external_string_table_.Iterate(&external_string_table_visitor);
1945
1946 class StringTableVisitorAdapter : public ObjectVisitor {
1947 public:
1948 explicit StringTableVisitorAdapter(
1949 v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {}
1950 virtual void VisitPointers(Object** start, Object** end) {
1951 for (Object** p = start; p < end; p++) {
1952 if ((*p)->IsExternalString()) {
1953 ASSERT((*p)->IsInternalizedString());
1954 visitor_->VisitExternalString(Utils::ToLocal(
1955 Handle<String>(String::cast(*p))));
1956 }
1957 }
1958 }
1959 private:
1960 v8::ExternalResourceVisitor* visitor_;
1961 } string_table_visitor(visitor);
1962
1963 string_table()->IterateElements(&string_table_visitor);
1964 } 1959 }
1965 1960
1966 1961
1967 class NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> { 1962 class NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> {
1968 public: 1963 public:
1969 static inline void VisitPointer(Heap* heap, Object** p) { 1964 static inline void VisitPointer(Heap* heap, Object** p) {
1970 Object* object = *p; 1965 Object* object = *p;
1971 if (!heap->InNewSpace(object)) return; 1966 if (!heap->InNewSpace(object)) return;
1972 Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p), 1967 Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p),
1973 reinterpret_cast<HeapObject*>(object)); 1968 reinterpret_cast<HeapObject*>(object));
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
2163 heap->CopyBlock(target->address(), source->address(), size); 2158 heap->CopyBlock(target->address(), source->address(), size);
2164 2159
2165 // Set the forwarding address. 2160 // Set the forwarding address.
2166 source->set_map_word(MapWord::FromForwardingAddress(target)); 2161 source->set_map_word(MapWord::FromForwardingAddress(target));
2167 2162
2168 if (logging_and_profiling_mode == LOGGING_AND_PROFILING_ENABLED) { 2163 if (logging_and_profiling_mode == LOGGING_AND_PROFILING_ENABLED) {
2169 // Update NewSpace stats if necessary. 2164 // Update NewSpace stats if necessary.
2170 RecordCopiedObject(heap, target); 2165 RecordCopiedObject(heap, target);
2171 Isolate* isolate = heap->isolate(); 2166 Isolate* isolate = heap->isolate();
2172 HeapProfiler* heap_profiler = isolate->heap_profiler(); 2167 HeapProfiler* heap_profiler = isolate->heap_profiler();
2173 if (heap_profiler->is_profiling()) { 2168 if (heap_profiler->is_tracking_object_moves()) {
2174 heap_profiler->ObjectMoveEvent(source->address(), target->address(), 2169 heap_profiler->ObjectMoveEvent(source->address(), target->address(),
2175 size); 2170 size);
2176 } 2171 }
2177 if (isolate->logger()->is_logging_code_events() || 2172 if (isolate->logger()->is_logging_code_events() ||
2178 isolate->cpu_profiler()->is_profiling()) { 2173 isolate->cpu_profiler()->is_profiling()) {
2179 if (target->IsSharedFunctionInfo()) { 2174 if (target->IsSharedFunctionInfo()) {
2180 PROFILE(isolate, SharedFunctionInfoMoveEvent( 2175 PROFILE(isolate, SharedFunctionInfoMoveEvent(
2181 source->address(), target->address())); 2176 source->address(), target->address()));
2182 } 2177 }
2183 } 2178 }
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
2414 LOGGING_AND_PROFILING_ENABLED>::Initialize(); 2409 LOGGING_AND_PROFILING_ENABLED>::Initialize();
2415 ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_ENABLED>::Initialize(); 2410 ScavengingVisitor<IGNORE_MARKS, LOGGING_AND_PROFILING_ENABLED>::Initialize();
2416 } 2411 }
2417 2412
2418 2413
2419 void Heap::SelectScavengingVisitorsTable() { 2414 void Heap::SelectScavengingVisitorsTable() {
2420 bool logging_and_profiling = 2415 bool logging_and_profiling =
2421 isolate()->logger()->is_logging() || 2416 isolate()->logger()->is_logging() ||
2422 isolate()->cpu_profiler()->is_profiling() || 2417 isolate()->cpu_profiler()->is_profiling() ||
2423 (isolate()->heap_profiler() != NULL && 2418 (isolate()->heap_profiler() != NULL &&
2424 isolate()->heap_profiler()->is_profiling()); 2419 isolate()->heap_profiler()->is_tracking_object_moves());
2425 2420
2426 if (!incremental_marking()->IsMarking()) { 2421 if (!incremental_marking()->IsMarking()) {
2427 if (!logging_and_profiling) { 2422 if (!logging_and_profiling) {
2428 scavenging_visitors_table_.CopyFrom( 2423 scavenging_visitors_table_.CopyFrom(
2429 ScavengingVisitor<IGNORE_MARKS, 2424 ScavengingVisitor<IGNORE_MARKS,
2430 LOGGING_AND_PROFILING_DISABLED>::GetTable()); 2425 LOGGING_AND_PROFILING_DISABLED>::GetTable());
2431 } else { 2426 } else {
2432 scavenging_visitors_table_.CopyFrom( 2427 scavenging_visitors_table_.CopyFrom(
2433 ScavengingVisitor<IGNORE_MARKS, 2428 ScavengingVisitor<IGNORE_MARKS,
2434 LOGGING_AND_PROFILING_ENABLED>::GetTable()); 2429 LOGGING_AND_PROFILING_ENABLED>::GetTable());
(...skipping 1526 matching lines...) Expand 10 before | Expand all | Expand 10 after
3961 } 3956 }
3962 3957
3963 3958
3964 MaybeObject* Heap::AllocateSubString(String* buffer, 3959 MaybeObject* Heap::AllocateSubString(String* buffer,
3965 int start, 3960 int start,
3966 int end, 3961 int end,
3967 PretenureFlag pretenure) { 3962 PretenureFlag pretenure) {
3968 int length = end - start; 3963 int length = end - start;
3969 if (length <= 0) { 3964 if (length <= 0) {
3970 return empty_string(); 3965 return empty_string();
3971 } else if (length == 1) { 3966 }
3967
3968 // Make an attempt to flatten the buffer to reduce access time.
3969 buffer = buffer->TryFlattenGetString();
3970
3971 if (length == 1) {
3972 return LookupSingleCharacterStringFromCode(buffer->Get(start)); 3972 return LookupSingleCharacterStringFromCode(buffer->Get(start));
3973 } else if (length == 2) { 3973 } else if (length == 2) {
3974 // Optimization for 2-byte strings often used as keys in a decompression 3974 // Optimization for 2-byte strings often used as keys in a decompression
3975 // dictionary. Check whether we already have the string in the string 3975 // dictionary. Check whether we already have the string in the string
3976 // table to prevent creation of many unnecessary strings. 3976 // table to prevent creation of many unnecessary strings.
3977 uint16_t c1 = buffer->Get(start); 3977 uint16_t c1 = buffer->Get(start);
3978 uint16_t c2 = buffer->Get(start + 1); 3978 uint16_t c2 = buffer->Get(start + 1);
3979 return MakeOrFindTwoCharacterString(this, c1, c2); 3979 return MakeOrFindTwoCharacterString(this, c1, c2);
3980 } 3980 }
3981 3981
3982 // Make an attempt to flatten the buffer to reduce access time.
3983 buffer = buffer->TryFlattenGetString();
3984
3985 if (!FLAG_string_slices || 3982 if (!FLAG_string_slices ||
3986 !buffer->IsFlat() || 3983 !buffer->IsFlat() ||
3987 length < SlicedString::kMinLength || 3984 length < SlicedString::kMinLength ||
3988 pretenure == TENURED) { 3985 pretenure == TENURED) {
3989 Object* result; 3986 Object* result;
3990 // WriteToFlat takes care of the case when an indirect string has a 3987 // WriteToFlat takes care of the case when an indirect string has a
3991 // different encoding from its underlying string. These encodings may 3988 // different encoding from its underlying string. These encodings may
3992 // differ because of externalization. 3989 // differ because of externalization.
3993 bool is_one_byte = buffer->IsOneByteRepresentation(); 3990 bool is_one_byte = buffer->IsOneByteRepresentation();
3994 { MaybeObject* maybe_result = is_one_byte 3991 { MaybeObject* maybe_result = is_one_byte
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
4350 4347
4351 #ifdef VERIFY_HEAP 4348 #ifdef VERIFY_HEAP
4352 if (FLAG_verify_heap) { 4349 if (FLAG_verify_heap) {
4353 code->Verify(); 4350 code->Verify();
4354 } 4351 }
4355 #endif 4352 #endif
4356 return new_code; 4353 return new_code;
4357 } 4354 }
4358 4355
4359 4356
4357 void Heap::InitializeAllocationMemento(AllocationMemento* memento,
4358 AllocationSite* allocation_site) {
4359 memento->set_map_no_write_barrier(allocation_memento_map());
4360 ASSERT(allocation_site->map() == allocation_site_map());
4361 memento->set_allocation_site(allocation_site, SKIP_WRITE_BARRIER);
4362 if (FLAG_allocation_site_pretenuring) {
4363 allocation_site->IncrementMementoCreateCount();
4364 }
4365 }
4366
4367
4360 MaybeObject* Heap::AllocateWithAllocationSite(Map* map, AllocationSpace space, 4368 MaybeObject* Heap::AllocateWithAllocationSite(Map* map, AllocationSpace space,
4361 Handle<AllocationSite> allocation_site) { 4369 Handle<AllocationSite> allocation_site) {
4362 ASSERT(gc_state_ == NOT_IN_GC); 4370 ASSERT(gc_state_ == NOT_IN_GC);
4363 ASSERT(map->instance_type() != MAP_TYPE); 4371 ASSERT(map->instance_type() != MAP_TYPE);
4364 // If allocation failures are disallowed, we may allocate in a different 4372 // If allocation failures are disallowed, we may allocate in a different
4365 // space when new space is full and the object is not a large object. 4373 // space when new space is full and the object is not a large object.
4366 AllocationSpace retry_space = 4374 AllocationSpace retry_space =
4367 (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type()); 4375 (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type());
4368 int size = map->instance_size() + AllocationMemento::kSize; 4376 int size = map->instance_size() + AllocationMemento::kSize;
4369 Object* result; 4377 Object* result;
4370 MaybeObject* maybe_result = AllocateRaw(size, space, retry_space); 4378 MaybeObject* maybe_result = AllocateRaw(size, space, retry_space);
4371 if (!maybe_result->ToObject(&result)) return maybe_result; 4379 if (!maybe_result->ToObject(&result)) return maybe_result;
4372 // No need for write barrier since object is white and map is in old space. 4380 // No need for write barrier since object is white and map is in old space.
4373 HeapObject::cast(result)->set_map_no_write_barrier(map); 4381 HeapObject::cast(result)->set_map_no_write_barrier(map);
4374 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>( 4382 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
4375 reinterpret_cast<Address>(result) + map->instance_size()); 4383 reinterpret_cast<Address>(result) + map->instance_size());
4376 alloc_memento->set_map_no_write_barrier(allocation_memento_map()); 4384 InitializeAllocationMemento(alloc_memento, *allocation_site);
4377 ASSERT(allocation_site->map() == allocation_site_map());
4378 alloc_memento->set_allocation_site(*allocation_site, SKIP_WRITE_BARRIER);
4379 return result; 4385 return result;
4380 } 4386 }
4381 4387
4382 4388
4383 MaybeObject* Heap::Allocate(Map* map, AllocationSpace space) { 4389 MaybeObject* Heap::Allocate(Map* map, AllocationSpace space) {
4384 ASSERT(gc_state_ == NOT_IN_GC); 4390 ASSERT(gc_state_ == NOT_IN_GC);
4385 ASSERT(map->instance_type() != MAP_TYPE); 4391 ASSERT(map->instance_type() != MAP_TYPE);
4386 // If allocation failures are disallowed, we may allocate in a different 4392 // If allocation failures are disallowed, we may allocate in a different
4387 // space when new space is full and the object is not a large object. 4393 // space when new space is full and the object is not a large object.
4388 AllocationSpace retry_space = 4394 AllocationSpace retry_space =
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
4801 MaybeObject* Heap::CopyJSObject(JSObject* source, AllocationSite* site) { 4807 MaybeObject* Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
4802 // Never used to copy functions. If functions need to be copied we 4808 // Never used to copy functions. If functions need to be copied we
4803 // have to be careful to clear the literals array. 4809 // have to be careful to clear the literals array.
4804 SLOW_ASSERT(!source->IsJSFunction()); 4810 SLOW_ASSERT(!source->IsJSFunction());
4805 4811
4806 // Make the clone. 4812 // Make the clone.
4807 Map* map = source->map(); 4813 Map* map = source->map();
4808 int object_size = map->instance_size(); 4814 int object_size = map->instance_size();
4809 Object* clone; 4815 Object* clone;
4810 4816
4811 ASSERT(site == NULL || (AllocationSite::CanTrack(map->instance_type()) && 4817 ASSERT(site == NULL || AllocationSite::CanTrack(map->instance_type()));
4812 map->instance_type() == JS_ARRAY_TYPE));
4813 4818
4814 WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER; 4819 WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER;
4815 4820
4816 // If we're forced to always allocate, we use the general allocation 4821 // If we're forced to always allocate, we use the general allocation
4817 // functions which may leave us with an object in old space. 4822 // functions which may leave us with an object in old space.
4818 if (always_allocate()) { 4823 if (always_allocate()) {
4819 { MaybeObject* maybe_clone = 4824 { MaybeObject* maybe_clone =
4820 AllocateRaw(object_size, NEW_SPACE, OLD_POINTER_SPACE); 4825 AllocateRaw(object_size, NEW_SPACE, OLD_POINTER_SPACE);
4821 if (!maybe_clone->ToObject(&clone)) return maybe_clone; 4826 if (!maybe_clone->ToObject(&clone)) return maybe_clone;
4822 } 4827 }
(...skipping 18 matching lines...) Expand all
4841 SLOW_ASSERT(InNewSpace(clone)); 4846 SLOW_ASSERT(InNewSpace(clone));
4842 // Since we know the clone is allocated in new space, we can copy 4847 // Since we know the clone is allocated in new space, we can copy
4843 // the contents without worrying about updating the write barrier. 4848 // the contents without worrying about updating the write barrier.
4844 CopyBlock(HeapObject::cast(clone)->address(), 4849 CopyBlock(HeapObject::cast(clone)->address(),
4845 source->address(), 4850 source->address(),
4846 object_size); 4851 object_size);
4847 4852
4848 if (site != NULL) { 4853 if (site != NULL) {
4849 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>( 4854 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
4850 reinterpret_cast<Address>(clone) + object_size); 4855 reinterpret_cast<Address>(clone) + object_size);
4851 alloc_memento->set_map_no_write_barrier(allocation_memento_map()); 4856 InitializeAllocationMemento(alloc_memento, site);
4852 ASSERT(site->map() == allocation_site_map());
4853 alloc_memento->set_allocation_site(site, SKIP_WRITE_BARRIER);
4854 HeapProfiler* profiler = isolate()->heap_profiler();
4855 if (profiler->is_tracking_allocations()) {
4856 profiler->UpdateObjectSizeEvent(HeapObject::cast(clone)->address(),
4857 object_size);
4858 profiler->NewObjectEvent(alloc_memento->address(),
4859 AllocationMemento::kSize);
4860 }
4861 } 4857 }
4862 } 4858 }
4863 4859
4864 SLOW_ASSERT( 4860 SLOW_ASSERT(
4865 JSObject::cast(clone)->GetElementsKind() == source->GetElementsKind()); 4861 JSObject::cast(clone)->GetElementsKind() == source->GetElementsKind());
4866 FixedArrayBase* elements = FixedArrayBase::cast(source->elements()); 4862 FixedArrayBase* elements = FixedArrayBase::cast(source->elements());
4867 FixedArray* properties = FixedArray::cast(source->properties()); 4863 FixedArray* properties = FixedArray::cast(source->properties());
4868 // Update elements if necessary. 4864 // Update elements if necessary.
4869 if (elements->length() > 0) { 4865 if (elements->length() > 0) {
4870 Object* elem; 4866 Object* elem;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
4974 // Reset the map for the object. 4970 // Reset the map for the object.
4975 object->set_map(constructor->initial_map()); 4971 object->set_map(constructor->initial_map());
4976 4972
4977 // Reinitialize the object from the constructor map. 4973 // Reinitialize the object from the constructor map.
4978 InitializeJSObjectFromMap(object, FixedArray::cast(properties), map); 4974 InitializeJSObjectFromMap(object, FixedArray::cast(properties), map);
4979 return object; 4975 return object;
4980 } 4976 }
4981 4977
4982 4978
4983 MaybeObject* Heap::AllocateStringFromOneByte(Vector<const uint8_t> string, 4979 MaybeObject* Heap::AllocateStringFromOneByte(Vector<const uint8_t> string,
4984 PretenureFlag pretenure) { 4980 PretenureFlag pretenure) {
4985 int length = string.length(); 4981 int length = string.length();
4986 if (length == 1) { 4982 if (length == 1) {
4987 return Heap::LookupSingleCharacterStringFromCode(string[0]); 4983 return Heap::LookupSingleCharacterStringFromCode(string[0]);
4988 } 4984 }
4989 Object* result; 4985 Object* result;
4990 { MaybeObject* maybe_result = 4986 { MaybeObject* maybe_result =
4991 AllocateRawOneByteString(string.length(), pretenure); 4987 AllocateRawOneByteString(string.length(), pretenure);
4992 if (!maybe_result->ToObject(&result)) return maybe_result; 4988 if (!maybe_result->ToObject(&result)) return maybe_result;
4993 } 4989 }
4994 4990
(...skipping 2966 matching lines...) Expand 10 before | Expand all | Expand 10 after
7961 static_cast<int>(object_sizes_last_time_[index])); 7957 static_cast<int>(object_sizes_last_time_[index]));
7962 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 7958 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
7963 #undef ADJUST_LAST_TIME_OBJECT_COUNT 7959 #undef ADJUST_LAST_TIME_OBJECT_COUNT
7964 7960
7965 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 7961 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
7966 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 7962 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
7967 ClearObjectStats(); 7963 ClearObjectStats();
7968 } 7964 }
7969 7965
7970 } } // namespace v8::internal 7966 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698