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

Side by Side Diff: src/heap.cc

Issue 157503002: A64: Synchronize with r18444. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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.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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 #include "mark-compact.h" 42 #include "mark-compact.h"
43 #include "natives.h" 43 #include "natives.h"
44 #include "objects-visiting.h" 44 #include "objects-visiting.h"
45 #include "objects-visiting-inl.h" 45 #include "objects-visiting-inl.h"
46 #include "once.h" 46 #include "once.h"
47 #include "runtime-profiler.h" 47 #include "runtime-profiler.h"
48 #include "scopeinfo.h" 48 #include "scopeinfo.h"
49 #include "snapshot.h" 49 #include "snapshot.h"
50 #include "store-buffer.h" 50 #include "store-buffer.h"
51 #include "utils/random-number-generator.h" 51 #include "utils/random-number-generator.h"
52 #include "v8conversions.h"
52 #include "v8threads.h" 53 #include "v8threads.h"
53 #include "v8utils.h" 54 #include "v8utils.h"
54 #include "vm-state-inl.h" 55 #include "vm-state-inl.h"
55 #if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP 56 #if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP
56 #include "regexp-macro-assembler.h" 57 #include "regexp-macro-assembler.h"
57 #include "arm/regexp-macro-assembler-arm.h" 58 #include "arm/regexp-macro-assembler-arm.h"
58 #endif 59 #endif
59 #if V8_TARGET_ARCH_MIPS && !V8_INTERPRETED_REGEXP 60 #if V8_TARGET_ARCH_MIPS && !V8_INTERPRETED_REGEXP
60 #include "regexp-macro-assembler.h" 61 #include "regexp-macro-assembler.h"
61 #include "mips/regexp-macro-assembler-mips.h" 62 #include "mips/regexp-macro-assembler-mips.h"
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 last_idle_notification_gc_count_init_(false), 142 last_idle_notification_gc_count_init_(false),
142 mark_sweeps_since_idle_round_started_(0), 143 mark_sweeps_since_idle_round_started_(0),
143 gc_count_at_last_idle_gc_(0), 144 gc_count_at_last_idle_gc_(0),
144 scavenges_since_last_idle_round_(kIdleScavengeThreshold), 145 scavenges_since_last_idle_round_(kIdleScavengeThreshold),
145 full_codegen_bytes_generated_(0), 146 full_codegen_bytes_generated_(0),
146 crankshaft_codegen_bytes_generated_(0), 147 crankshaft_codegen_bytes_generated_(0),
147 gcs_since_last_deopt_(0), 148 gcs_since_last_deopt_(0),
148 #ifdef VERIFY_HEAP 149 #ifdef VERIFY_HEAP
149 no_weak_object_verification_scope_depth_(0), 150 no_weak_object_verification_scope_depth_(0),
150 #endif 151 #endif
152 allocation_sites_scratchpad_length(0),
151 promotion_queue_(this), 153 promotion_queue_(this),
152 configured_(false), 154 configured_(false),
153 chunks_queued_for_free_(NULL), 155 chunks_queued_for_free_(NULL),
154 relocation_mutex_(NULL) { 156 relocation_mutex_(NULL) {
155 // Allow build-time customization of the max semispace size. Building 157 // Allow build-time customization of the max semispace size. Building
156 // V8 with snapshots and a non-default max semispace size is much 158 // V8 with snapshots and a non-default max semispace size is much
157 // easier if you can define it as part of the build environment. 159 // easier if you can define it as part of the build environment.
158 #if defined(V8_MAX_SEMISPACE_SIZE) 160 #if defined(V8_MAX_SEMISPACE_SIZE)
159 max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; 161 max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE;
160 #endif 162 #endif
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 new_space_.ReportStatistics(); 431 new_space_.ReportStatistics();
430 } 432 }
431 #else 433 #else
432 if (FLAG_log_gc) new_space_.ReportStatistics(); 434 if (FLAG_log_gc) new_space_.ReportStatistics();
433 #endif // DEBUG 435 #endif // DEBUG
434 } 436 }
435 437
436 438
437 void Heap::GarbageCollectionPrologue() { 439 void Heap::GarbageCollectionPrologue() {
438 { AllowHeapAllocation for_the_first_part_of_prologue; 440 { AllowHeapAllocation for_the_first_part_of_prologue;
439 isolate_->transcendental_cache()->Clear();
440 ClearJSFunctionResultCaches(); 441 ClearJSFunctionResultCaches();
441 gc_count_++; 442 gc_count_++;
442 unflattened_strings_length_ = 0; 443 unflattened_strings_length_ = 0;
443 444
444 if (FLAG_flush_code && FLAG_flush_code_incrementally) { 445 if (FLAG_flush_code && FLAG_flush_code_incrementally) {
445 mark_compact_collector()->EnableCodeFlushing(true); 446 mark_compact_collector()->EnableCodeFlushing(true);
446 } 447 }
447 448
448 #ifdef VERIFY_HEAP 449 #ifdef VERIFY_HEAP
449 if (FLAG_verify_heap) { 450 if (FLAG_verify_heap) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 void Heap::RepairFreeListsAfterBoot() { 498 void Heap::RepairFreeListsAfterBoot() {
498 PagedSpaces spaces(this); 499 PagedSpaces spaces(this);
499 for (PagedSpace* space = spaces.next(); 500 for (PagedSpace* space = spaces.next();
500 space != NULL; 501 space != NULL;
501 space = spaces.next()) { 502 space = spaces.next()) {
502 space->RepairFreeListsAfterBoot(); 503 space->RepairFreeListsAfterBoot();
503 } 504 }
504 } 505 }
505 506
506 507
507 void Heap::GarbageCollectionEpilogue() { 508 void Heap::ProcessPretenuringFeedback() {
508 if (FLAG_allocation_site_pretenuring) { 509 if (FLAG_allocation_site_pretenuring) {
509 int tenure_decisions = 0; 510 int tenure_decisions = 0;
510 int dont_tenure_decisions = 0; 511 int dont_tenure_decisions = 0;
511 int allocation_mementos_found = 0; 512 int allocation_mementos_found = 0;
513 int allocation_sites = 0;
514 int active_allocation_sites = 0;
512 515
513 Object* cur = allocation_sites_list(); 516 // If the scratchpad overflowed, we have to iterate over the allocation
514 while (cur->IsAllocationSite()) { 517 // stites list.
515 AllocationSite* casted = AllocationSite::cast(cur); 518 bool use_scratchpad =
516 allocation_mementos_found += casted->memento_found_count()->value(); 519 allocation_sites_scratchpad_length < kAllocationSiteScratchpadSize;
517 if (casted->DigestPretenuringFeedback()) { 520
518 if (casted->GetPretenureMode() == TENURED) { 521 int i = 0;
522 Object* list_element = allocation_sites_list();
523 while (use_scratchpad ?
524 i < allocation_sites_scratchpad_length :
525 list_element->IsAllocationSite()) {
526 AllocationSite* site = use_scratchpad ?
527 allocation_sites_scratchpad[i] : AllocationSite::cast(list_element);
528 allocation_mementos_found += site->memento_found_count()->value();
529 if (site->memento_found_count()->value() > 0) {
530 active_allocation_sites++;
531 }
532 if (site->DigestPretenuringFeedback()) {
533 if (site->GetPretenureMode() == TENURED) {
519 tenure_decisions++; 534 tenure_decisions++;
520 } else { 535 } else {
521 dont_tenure_decisions++; 536 dont_tenure_decisions++;
522 } 537 }
523 } 538 }
524 cur = casted->weak_next(); 539 allocation_sites++;
540 if (use_scratchpad) {
541 i++;
542 } else {
543 list_element = site->weak_next();
544 }
525 } 545 }
546 allocation_sites_scratchpad_length = 0;
526 547
527 // TODO(mvstanton): Pretenure decisions are only made once for an allocation 548 // TODO(mvstanton): Pretenure decisions are only made once for an allocation
528 // site. Find a sane way to decide about revisiting the decision later. 549 // site. Find a sane way to decide about revisiting the decision later.
529 550
530 if (FLAG_trace_track_allocation_sites && 551 if (FLAG_trace_track_allocation_sites &&
531 (allocation_mementos_found > 0 || 552 (allocation_mementos_found > 0 ||
532 tenure_decisions > 0 || 553 tenure_decisions > 0 ||
533 dont_tenure_decisions > 0)) { 554 dont_tenure_decisions > 0)) {
534 PrintF("GC: (#mementos, #tenure decisions, #donttenure decisions) " 555 PrintF("GC: (mode, #visited allocation sites, #active allocation sites, "
535 "(%d, %d, %d)\n", 556 "#mementos, #tenure decisions, #donttenure decisions) "
557 "(%s, %d, %d, %d, %d, %d)\n",
558 use_scratchpad ? "use scratchpad" : "use list",
559 allocation_sites,
560 active_allocation_sites,
536 allocation_mementos_found, 561 allocation_mementos_found,
537 tenure_decisions, 562 tenure_decisions,
538 dont_tenure_decisions); 563 dont_tenure_decisions);
539 } 564 }
540 } 565 }
566 }
541 567
568
569 void Heap::GarbageCollectionEpilogue() {
542 store_buffer()->GCEpilogue(); 570 store_buffer()->GCEpilogue();
543 571
544 // In release mode, we only zap the from space under heap verification. 572 // In release mode, we only zap the from space under heap verification.
545 if (Heap::ShouldZapGarbage()) { 573 if (Heap::ShouldZapGarbage()) {
546 ZapFromSpace(); 574 ZapFromSpace();
547 } 575 }
548 576
549 #ifdef VERIFY_HEAP 577 #ifdef VERIFY_HEAP
550 if (FLAG_verify_heap) { 578 if (FLAG_verify_heap) {
551 Verify(); 579 Verify();
(...skipping 989 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 &IsUnscavengedHeapObject); 1569 &IsUnscavengedHeapObject);
1542 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( 1570 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots(
1543 &scavenge_visitor); 1571 &scavenge_visitor);
1544 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); 1572 new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
1545 1573
1546 UpdateNewSpaceReferencesInExternalStringTable( 1574 UpdateNewSpaceReferencesInExternalStringTable(
1547 &UpdateNewSpaceReferenceInExternalStringTableEntry); 1575 &UpdateNewSpaceReferenceInExternalStringTableEntry);
1548 1576
1549 promotion_queue_.Destroy(); 1577 promotion_queue_.Destroy();
1550 1578
1551 if (!FLAG_watch_ic_patching) {
1552 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge();
1553 }
1554 incremental_marking()->UpdateMarkingDequeAfterScavenge(); 1579 incremental_marking()->UpdateMarkingDequeAfterScavenge();
1555 1580
1556 ScavengeWeakObjectRetainer weak_object_retainer(this); 1581 ScavengeWeakObjectRetainer weak_object_retainer(this);
1557 ProcessWeakReferences(&weak_object_retainer); 1582 ProcessWeakReferences(&weak_object_retainer);
1558 1583
1559 ASSERT(new_space_front == new_space_.top()); 1584 ASSERT(new_space_front == new_space_.top());
1560 1585
1561 // Set age mark. 1586 // Set age mark.
1562 new_space_.set_age_mark(new_space_.top()); 1587 new_space_.set_age_mark(new_space_.top());
1563 1588
1564 new_space_.LowerInlineAllocationLimit( 1589 new_space_.LowerInlineAllocationLimit(
1565 new_space_.inline_allocation_limit_step()); 1590 new_space_.inline_allocation_limit_step());
1566 1591
1567 // Update how much has survived scavenge. 1592 // Update how much has survived scavenge.
1568 IncrementYoungSurvivorsCounter(static_cast<int>( 1593 IncrementYoungSurvivorsCounter(static_cast<int>(
1569 (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size())); 1594 (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size()));
1570 1595
1596 ProcessPretenuringFeedback();
1597
1571 LOG(isolate_, ResourceEvent("scavenge", "end")); 1598 LOG(isolate_, ResourceEvent("scavenge", "end"));
1572 1599
1573 gc_state_ = NOT_IN_GC; 1600 gc_state_ = NOT_IN_GC;
1574 1601
1575 scavenges_since_last_idle_round_++; 1602 scavenges_since_last_idle_round_++;
1576 } 1603 }
1577 1604
1578 1605
1579 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, 1606 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
1580 Object** p) { 1607 Object** p) {
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
1934 Object* allocation_site_obj = 1961 Object* allocation_site_obj =
1935 VisitWeakList<AllocationSite>(this, 1962 VisitWeakList<AllocationSite>(this,
1936 allocation_sites_list(), 1963 allocation_sites_list(),
1937 retainer, record_slots); 1964 retainer, record_slots);
1938 set_allocation_sites_list(allocation_site_obj); 1965 set_allocation_sites_list(allocation_site_obj);
1939 } 1966 }
1940 1967
1941 1968
1942 void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) { 1969 void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) {
1943 DisallowHeapAllocation no_allocation; 1970 DisallowHeapAllocation no_allocation;
1944 1971 // All external strings are listed in the external string table.
1945 // Both the external string table and the string table may contain
1946 // external strings, but neither lists them exhaustively, nor is the
1947 // intersection set empty. Therefore we iterate over the external string
1948 // table first, ignoring internalized strings, and then over the
1949 // internalized string table.
1950 1972
1951 class ExternalStringTableVisitorAdapter : public ObjectVisitor { 1973 class ExternalStringTableVisitorAdapter : public ObjectVisitor {
1952 public: 1974 public:
1953 explicit ExternalStringTableVisitorAdapter( 1975 explicit ExternalStringTableVisitorAdapter(
1954 v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {} 1976 v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {}
1955 virtual void VisitPointers(Object** start, Object** end) { 1977 virtual void VisitPointers(Object** start, Object** end) {
1956 for (Object** p = start; p < end; p++) { 1978 for (Object** p = start; p < end; p++) {
1957 // Visit non-internalized external strings, 1979 ASSERT((*p)->IsExternalString());
1958 // since internalized strings are listed in the string table. 1980 visitor_->VisitExternalString(Utils::ToLocal(
1959 if (!(*p)->IsInternalizedString()) { 1981 Handle<String>(String::cast(*p))));
1960 ASSERT((*p)->IsExternalString());
1961 visitor_->VisitExternalString(Utils::ToLocal(
1962 Handle<String>(String::cast(*p))));
1963 }
1964 } 1982 }
1965 } 1983 }
1966 private: 1984 private:
1967 v8::ExternalResourceVisitor* visitor_; 1985 v8::ExternalResourceVisitor* visitor_;
1968 } external_string_table_visitor(visitor); 1986 } external_string_table_visitor(visitor);
1969 1987
1970 external_string_table_.Iterate(&external_string_table_visitor); 1988 external_string_table_.Iterate(&external_string_table_visitor);
1971
1972 class StringTableVisitorAdapter : public ObjectVisitor {
1973 public:
1974 explicit StringTableVisitorAdapter(
1975 v8::ExternalResourceVisitor* visitor) : visitor_(visitor) {}
1976 virtual void VisitPointers(Object** start, Object** end) {
1977 for (Object** p = start; p < end; p++) {
1978 if ((*p)->IsExternalString()) {
1979 ASSERT((*p)->IsInternalizedString());
1980 visitor_->VisitExternalString(Utils::ToLocal(
1981 Handle<String>(String::cast(*p))));
1982 }
1983 }
1984 }
1985 private:
1986 v8::ExternalResourceVisitor* visitor_;
1987 } string_table_visitor(visitor);
1988
1989 string_table()->IterateElements(&string_table_visitor);
1990 } 1989 }
1991 1990
1992 1991
1993 class NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> { 1992 class NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> {
1994 public: 1993 public:
1995 static inline void VisitPointer(Heap* heap, Object** p) { 1994 static inline void VisitPointer(Heap* heap, Object** p) {
1996 Object* object = *p; 1995 Object* object = *p;
1997 if (!heap->InNewSpace(object)) return; 1996 if (!heap->InNewSpace(object)) return;
1998 Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p), 1997 Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p),
1999 reinterpret_cast<HeapObject*>(object)); 1998 reinterpret_cast<HeapObject*>(object));
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after
2639 AllocatePartialMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); 2638 AllocatePartialMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
2640 if (!maybe_obj->ToObject(&obj)) return false; 2639 if (!maybe_obj->ToObject(&obj)) return false;
2641 } 2640 }
2642 set_fixed_array_map(Map::cast(obj)); 2641 set_fixed_array_map(Map::cast(obj));
2643 2642
2644 { MaybeObject* maybe_obj = AllocatePartialMap(ODDBALL_TYPE, Oddball::kSize); 2643 { MaybeObject* maybe_obj = AllocatePartialMap(ODDBALL_TYPE, Oddball::kSize);
2645 if (!maybe_obj->ToObject(&obj)) return false; 2644 if (!maybe_obj->ToObject(&obj)) return false;
2646 } 2645 }
2647 set_oddball_map(Map::cast(obj)); 2646 set_oddball_map(Map::cast(obj));
2648 2647
2648 { MaybeObject* maybe_obj =
2649 AllocatePartialMap(CONSTANT_POOL_ARRAY_TYPE, kVariableSizeSentinel);
2650 if (!maybe_obj->ToObject(&obj)) return false;
2651 }
2652 set_constant_pool_array_map(Map::cast(obj));
2653
2649 // Allocate the empty array. 2654 // Allocate the empty array.
2650 { MaybeObject* maybe_obj = AllocateEmptyFixedArray(); 2655 { MaybeObject* maybe_obj = AllocateEmptyFixedArray();
2651 if (!maybe_obj->ToObject(&obj)) return false; 2656 if (!maybe_obj->ToObject(&obj)) return false;
2652 } 2657 }
2653 set_empty_fixed_array(FixedArray::cast(obj)); 2658 set_empty_fixed_array(FixedArray::cast(obj));
2654 2659
2655 { MaybeObject* maybe_obj = Allocate(oddball_map(), OLD_POINTER_SPACE); 2660 { MaybeObject* maybe_obj = Allocate(oddball_map(), OLD_POINTER_SPACE);
2656 if (!maybe_obj->ToObject(&obj)) return false; 2661 if (!maybe_obj->ToObject(&obj)) return false;
2657 } 2662 }
2658 set_null_value(Oddball::cast(obj)); 2663 set_null_value(Oddball::cast(obj));
2659 Oddball::cast(obj)->set_kind(Oddball::kNull); 2664 Oddball::cast(obj)->set_kind(Oddball::kNull);
2660 2665
2661 { MaybeObject* maybe_obj = Allocate(oddball_map(), OLD_POINTER_SPACE); 2666 { MaybeObject* maybe_obj = Allocate(oddball_map(), OLD_POINTER_SPACE);
2662 if (!maybe_obj->ToObject(&obj)) return false; 2667 if (!maybe_obj->ToObject(&obj)) return false;
2663 } 2668 }
2664 set_undefined_value(Oddball::cast(obj)); 2669 set_undefined_value(Oddball::cast(obj));
2665 Oddball::cast(obj)->set_kind(Oddball::kUndefined); 2670 Oddball::cast(obj)->set_kind(Oddball::kUndefined);
2666 ASSERT(!InNewSpace(undefined_value())); 2671 ASSERT(!InNewSpace(undefined_value()));
2667 2672
2668 // Allocate the empty descriptor array. 2673 // Allocate the empty descriptor array.
2669 { MaybeObject* maybe_obj = AllocateEmptyFixedArray(); 2674 { MaybeObject* maybe_obj = AllocateEmptyFixedArray();
2670 if (!maybe_obj->ToObject(&obj)) return false; 2675 if (!maybe_obj->ToObject(&obj)) return false;
2671 } 2676 }
2672 set_empty_descriptor_array(DescriptorArray::cast(obj)); 2677 set_empty_descriptor_array(DescriptorArray::cast(obj));
2673 2678
2679 // Allocate the constant pool array.
2680 { MaybeObject* maybe_obj = AllocateEmptyConstantPoolArray();
2681 if (!maybe_obj->ToObject(&obj)) return false;
2682 }
2683 set_empty_constant_pool_array(ConstantPoolArray::cast(obj));
2684
2674 // Fix the instance_descriptors for the existing maps. 2685 // Fix the instance_descriptors for the existing maps.
2675 meta_map()->set_code_cache(empty_fixed_array()); 2686 meta_map()->set_code_cache(empty_fixed_array());
2676 meta_map()->set_dependent_code(DependentCode::cast(empty_fixed_array())); 2687 meta_map()->set_dependent_code(DependentCode::cast(empty_fixed_array()));
2677 meta_map()->init_back_pointer(undefined_value()); 2688 meta_map()->init_back_pointer(undefined_value());
2678 meta_map()->set_instance_descriptors(empty_descriptor_array()); 2689 meta_map()->set_instance_descriptors(empty_descriptor_array());
2679 2690
2680 fixed_array_map()->set_code_cache(empty_fixed_array()); 2691 fixed_array_map()->set_code_cache(empty_fixed_array());
2681 fixed_array_map()->set_dependent_code( 2692 fixed_array_map()->set_dependent_code(
2682 DependentCode::cast(empty_fixed_array())); 2693 DependentCode::cast(empty_fixed_array()));
2683 fixed_array_map()->init_back_pointer(undefined_value()); 2694 fixed_array_map()->init_back_pointer(undefined_value());
2684 fixed_array_map()->set_instance_descriptors(empty_descriptor_array()); 2695 fixed_array_map()->set_instance_descriptors(empty_descriptor_array());
2685 2696
2686 oddball_map()->set_code_cache(empty_fixed_array()); 2697 oddball_map()->set_code_cache(empty_fixed_array());
2687 oddball_map()->set_dependent_code(DependentCode::cast(empty_fixed_array())); 2698 oddball_map()->set_dependent_code(DependentCode::cast(empty_fixed_array()));
2688 oddball_map()->init_back_pointer(undefined_value()); 2699 oddball_map()->init_back_pointer(undefined_value());
2689 oddball_map()->set_instance_descriptors(empty_descriptor_array()); 2700 oddball_map()->set_instance_descriptors(empty_descriptor_array());
2690 2701
2702 constant_pool_array_map()->set_code_cache(empty_fixed_array());
2703 constant_pool_array_map()->set_dependent_code(
2704 DependentCode::cast(empty_fixed_array()));
2705 constant_pool_array_map()->init_back_pointer(undefined_value());
2706 constant_pool_array_map()->set_instance_descriptors(empty_descriptor_array());
2707
2691 // Fix prototype object for existing maps. 2708 // Fix prototype object for existing maps.
2692 meta_map()->set_prototype(null_value()); 2709 meta_map()->set_prototype(null_value());
2693 meta_map()->set_constructor(null_value()); 2710 meta_map()->set_constructor(null_value());
2694 2711
2695 fixed_array_map()->set_prototype(null_value()); 2712 fixed_array_map()->set_prototype(null_value());
2696 fixed_array_map()->set_constructor(null_value()); 2713 fixed_array_map()->set_constructor(null_value());
2697 2714
2698 oddball_map()->set_prototype(null_value()); 2715 oddball_map()->set_prototype(null_value());
2699 oddball_map()->set_constructor(null_value()); 2716 oddball_map()->set_constructor(null_value());
2700 2717
2718 constant_pool_array_map()->set_prototype(null_value());
2719 constant_pool_array_map()->set_constructor(null_value());
2720
2701 { MaybeObject* maybe_obj = 2721 { MaybeObject* maybe_obj =
2702 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); 2722 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
2703 if (!maybe_obj->ToObject(&obj)) return false; 2723 if (!maybe_obj->ToObject(&obj)) return false;
2704 } 2724 }
2705 set_fixed_cow_array_map(Map::cast(obj)); 2725 set_fixed_cow_array_map(Map::cast(obj));
2706 ASSERT(fixed_array_map() != fixed_cow_array_map()); 2726 ASSERT(fixed_array_map() != fixed_cow_array_map());
2707 2727
2708 { MaybeObject* maybe_obj = 2728 { MaybeObject* maybe_obj =
2709 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); 2729 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
2710 if (!maybe_obj->ToObject(&obj)) return false; 2730 if (!maybe_obj->ToObject(&obj)) return false;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2747 set_undetectable_ascii_string_map(Map::cast(obj)); 2767 set_undetectable_ascii_string_map(Map::cast(obj));
2748 Map::cast(obj)->set_is_undetectable(); 2768 Map::cast(obj)->set_is_undetectable();
2749 2769
2750 { MaybeObject* maybe_obj = 2770 { MaybeObject* maybe_obj =
2751 AllocateMap(FIXED_DOUBLE_ARRAY_TYPE, kVariableSizeSentinel); 2771 AllocateMap(FIXED_DOUBLE_ARRAY_TYPE, kVariableSizeSentinel);
2752 if (!maybe_obj->ToObject(&obj)) return false; 2772 if (!maybe_obj->ToObject(&obj)) return false;
2753 } 2773 }
2754 set_fixed_double_array_map(Map::cast(obj)); 2774 set_fixed_double_array_map(Map::cast(obj));
2755 2775
2756 { MaybeObject* maybe_obj = 2776 { MaybeObject* maybe_obj =
2757 AllocateMap(CONSTANT_POOL_ARRAY_TYPE, kVariableSizeSentinel);
2758 if (!maybe_obj->ToObject(&obj)) return false;
2759 }
2760 set_constant_pool_array_map(Map::cast(obj));
2761
2762 { MaybeObject* maybe_obj =
2763 AllocateMap(BYTE_ARRAY_TYPE, kVariableSizeSentinel); 2777 AllocateMap(BYTE_ARRAY_TYPE, kVariableSizeSentinel);
2764 if (!maybe_obj->ToObject(&obj)) return false; 2778 if (!maybe_obj->ToObject(&obj)) return false;
2765 } 2779 }
2766 set_byte_array_map(Map::cast(obj)); 2780 set_byte_array_map(Map::cast(obj));
2767 2781
2768 { MaybeObject* maybe_obj = 2782 { MaybeObject* maybe_obj =
2769 AllocateMap(FREE_SPACE_TYPE, kVariableSizeSentinel); 2783 AllocateMap(FREE_SPACE_TYPE, kVariableSizeSentinel);
2770 if (!maybe_obj->ToObject(&obj)) return false; 2784 if (!maybe_obj->ToObject(&obj)) return false;
2771 } 2785 }
2772 set_free_space_map(Map::cast(obj)); 2786 set_free_space_map(Map::cast(obj));
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after
3689 case kExternalDoubleArray: 3703 case kExternalDoubleArray:
3690 return kExternalDoubleArrayMapRootIndex; 3704 return kExternalDoubleArrayMapRootIndex;
3691 case kExternalPixelArray: 3705 case kExternalPixelArray:
3692 return kExternalPixelArrayMapRootIndex; 3706 return kExternalPixelArrayMapRootIndex;
3693 default: 3707 default:
3694 UNREACHABLE(); 3708 UNREACHABLE();
3695 return kUndefinedValueRootIndex; 3709 return kUndefinedValueRootIndex;
3696 } 3710 }
3697 } 3711 }
3698 3712
3713
3699 Heap::RootListIndex Heap::RootIndexForEmptyExternalArray( 3714 Heap::RootListIndex Heap::RootIndexForEmptyExternalArray(
3700 ElementsKind elementsKind) { 3715 ElementsKind elementsKind) {
3701 switch (elementsKind) { 3716 switch (elementsKind) {
3702 case EXTERNAL_BYTE_ELEMENTS: 3717 case EXTERNAL_BYTE_ELEMENTS:
3703 return kEmptyExternalByteArrayRootIndex; 3718 return kEmptyExternalByteArrayRootIndex;
3704 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3719 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3705 return kEmptyExternalUnsignedByteArrayRootIndex; 3720 return kEmptyExternalUnsignedByteArrayRootIndex;
3706 case EXTERNAL_SHORT_ELEMENTS: 3721 case EXTERNAL_SHORT_ELEMENTS:
3707 return kEmptyExternalShortArrayRootIndex; 3722 return kEmptyExternalShortArrayRootIndex;
3708 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3723 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
(...skipping 14 matching lines...) Expand all
3723 } 3738 }
3724 } 3739 }
3725 3740
3726 3741
3727 ExternalArray* Heap::EmptyExternalArrayForMap(Map* map) { 3742 ExternalArray* Heap::EmptyExternalArrayForMap(Map* map) {
3728 return ExternalArray::cast( 3743 return ExternalArray::cast(
3729 roots_[RootIndexForEmptyExternalArray(map->elements_kind())]); 3744 roots_[RootIndexForEmptyExternalArray(map->elements_kind())]);
3730 } 3745 }
3731 3746
3732 3747
3733
3734
3735 MaybeObject* Heap::NumberFromDouble(double value, PretenureFlag pretenure) { 3748 MaybeObject* Heap::NumberFromDouble(double value, PretenureFlag pretenure) {
3736 // We need to distinguish the minus zero value and this cannot be 3749 // We need to distinguish the minus zero value and this cannot be
3737 // done after conversion to int. Doing this by comparing bit 3750 // done after conversion to int. Doing this by comparing bit
3738 // patterns is faster than using fpclassify() et al. 3751 // patterns is faster than using fpclassify() et al.
3739 static const DoubleRepresentation minus_zero(-0.0); 3752 if (IsMinusZero(value)) {
3740
3741 DoubleRepresentation rep(value);
3742 if (rep.bits == minus_zero.bits) {
3743 return AllocateHeapNumber(-0.0, pretenure); 3753 return AllocateHeapNumber(-0.0, pretenure);
3744 } 3754 }
3745 3755
3746 int int_value = FastD2I(value); 3756 int int_value = FastD2I(value);
3747 if (value == int_value && Smi::IsValid(int_value)) { 3757 if (value == int_value && Smi::IsValid(int_value)) {
3748 return Smi::FromInt(int_value); 3758 return Smi::FromInt(int_value);
3749 } 3759 }
3750 3760
3751 // Materialize the value in the heap. 3761 // Materialize the value in the heap.
3752 return AllocateHeapNumber(value, pretenure); 3762 return AllocateHeapNumber(value, pretenure);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3823 message->set_arguments(arguments); 3833 message->set_arguments(arguments);
3824 message->set_start_position(start_position); 3834 message->set_start_position(start_position);
3825 message->set_end_position(end_position); 3835 message->set_end_position(end_position);
3826 message->set_script(script); 3836 message->set_script(script);
3827 message->set_stack_trace(stack_trace); 3837 message->set_stack_trace(stack_trace);
3828 message->set_stack_frames(stack_frames); 3838 message->set_stack_frames(stack_frames);
3829 return result; 3839 return result;
3830 } 3840 }
3831 3841
3832 3842
3833
3834 // Returns true for a character in a range. Both limits are inclusive.
3835 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) {
3836 // This makes uses of the the unsigned wraparound.
3837 return character - from <= to - from;
3838 }
3839
3840
3841 MUST_USE_RESULT static inline MaybeObject* MakeOrFindTwoCharacterString(
3842 Heap* heap,
3843 uint16_t c1,
3844 uint16_t c2) {
3845 String* result;
3846 // Numeric strings have a different hash algorithm not known by
3847 // LookupTwoCharsStringIfExists, so we skip this step for such strings.
3848 if ((!Between(c1, '0', '9') || !Between(c2, '0', '9')) &&
3849 heap->string_table()->LookupTwoCharsStringIfExists(c1, c2, &result)) {
3850 return result;
3851 // Now we know the length is 2, we might as well make use of that fact
3852 // when building the new string.
3853 } else if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) {
3854 // We can do this.
3855 ASSERT(IsPowerOf2(String::kMaxOneByteCharCodeU + 1)); // because of this.
3856 Object* result;
3857 { MaybeObject* maybe_result = heap->AllocateRawOneByteString(2);
3858 if (!maybe_result->ToObject(&result)) return maybe_result;
3859 }
3860 uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
3861 dest[0] = static_cast<uint8_t>(c1);
3862 dest[1] = static_cast<uint8_t>(c2);
3863 return result;
3864 } else {
3865 Object* result;
3866 { MaybeObject* maybe_result = heap->AllocateRawTwoByteString(2);
3867 if (!maybe_result->ToObject(&result)) return maybe_result;
3868 }
3869 uc16* dest = SeqTwoByteString::cast(result)->GetChars();
3870 dest[0] = c1;
3871 dest[1] = c2;
3872 return result;
3873 }
3874 }
3875
3876
3877 MaybeObject* Heap::AllocateConsString(String* first, String* second) {
3878 int first_length = first->length();
3879 if (first_length == 0) {
3880 return second;
3881 }
3882
3883 int second_length = second->length();
3884 if (second_length == 0) {
3885 return first;
3886 }
3887
3888 int length = first_length + second_length;
3889
3890 // Optimization for 2-byte strings often used as keys in a decompression
3891 // dictionary. Check whether we already have the string in the string
3892 // table to prevent creation of many unneccesary strings.
3893 if (length == 2) {
3894 uint16_t c1 = first->Get(0);
3895 uint16_t c2 = second->Get(0);
3896 return MakeOrFindTwoCharacterString(this, c1, c2);
3897 }
3898
3899 bool first_is_one_byte = first->IsOneByteRepresentation();
3900 bool second_is_one_byte = second->IsOneByteRepresentation();
3901 bool is_one_byte = first_is_one_byte && second_is_one_byte;
3902 // Make sure that an out of memory exception is thrown if the length
3903 // of the new cons string is too large.
3904 if (length > String::kMaxLength || length < 0) {
3905 isolate()->context()->mark_out_of_memory();
3906 return Failure::OutOfMemoryException(0x4);
3907 }
3908
3909 bool is_one_byte_data_in_two_byte_string = false;
3910 if (!is_one_byte) {
3911 // At least one of the strings uses two-byte representation so we
3912 // can't use the fast case code for short ASCII strings below, but
3913 // we can try to save memory if all chars actually fit in ASCII.
3914 is_one_byte_data_in_two_byte_string =
3915 first->HasOnlyOneByteChars() && second->HasOnlyOneByteChars();
3916 if (is_one_byte_data_in_two_byte_string) {
3917 isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment();
3918 }
3919 }
3920
3921 // If the resulting string is small make a flat string.
3922 if (length < ConsString::kMinLength) {
3923 // Note that neither of the two inputs can be a slice because:
3924 STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength);
3925 ASSERT(first->IsFlat());
3926 ASSERT(second->IsFlat());
3927 if (is_one_byte) {
3928 Object* result;
3929 { MaybeObject* maybe_result = AllocateRawOneByteString(length);
3930 if (!maybe_result->ToObject(&result)) return maybe_result;
3931 }
3932 // Copy the characters into the new object.
3933 uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
3934 // Copy first part.
3935 const uint8_t* src;
3936 if (first->IsExternalString()) {
3937 src = ExternalAsciiString::cast(first)->GetChars();
3938 } else {
3939 src = SeqOneByteString::cast(first)->GetChars();
3940 }
3941 for (int i = 0; i < first_length; i++) *dest++ = src[i];
3942 // Copy second part.
3943 if (second->IsExternalString()) {
3944 src = ExternalAsciiString::cast(second)->GetChars();
3945 } else {
3946 src = SeqOneByteString::cast(second)->GetChars();
3947 }
3948 for (int i = 0; i < second_length; i++) *dest++ = src[i];
3949 return result;
3950 } else {
3951 if (is_one_byte_data_in_two_byte_string) {
3952 Object* result;
3953 { MaybeObject* maybe_result = AllocateRawOneByteString(length);
3954 if (!maybe_result->ToObject(&result)) return maybe_result;
3955 }
3956 // Copy the characters into the new object.
3957 uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
3958 String::WriteToFlat(first, dest, 0, first_length);
3959 String::WriteToFlat(second, dest + first_length, 0, second_length);
3960 isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment();
3961 return result;
3962 }
3963
3964 Object* result;
3965 { MaybeObject* maybe_result = AllocateRawTwoByteString(length);
3966 if (!maybe_result->ToObject(&result)) return maybe_result;
3967 }
3968 // Copy the characters into the new object.
3969 uc16* dest = SeqTwoByteString::cast(result)->GetChars();
3970 String::WriteToFlat(first, dest, 0, first_length);
3971 String::WriteToFlat(second, dest + first_length, 0, second_length);
3972 return result;
3973 }
3974 }
3975
3976 Map* map = (is_one_byte || is_one_byte_data_in_two_byte_string) ?
3977 cons_ascii_string_map() : cons_string_map();
3978
3979 Object* result;
3980 { MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
3981 if (!maybe_result->ToObject(&result)) return maybe_result;
3982 }
3983
3984 DisallowHeapAllocation no_gc;
3985 ConsString* cons_string = ConsString::cast(result);
3986 WriteBarrierMode mode = cons_string->GetWriteBarrierMode(no_gc);
3987 cons_string->set_length(length);
3988 cons_string->set_hash_field(String::kEmptyHashField);
3989 cons_string->set_first(first, mode);
3990 cons_string->set_second(second, mode);
3991 return result;
3992 }
3993
3994
3995 MaybeObject* Heap::AllocateSubString(String* buffer,
3996 int start,
3997 int end,
3998 PretenureFlag pretenure) {
3999 int length = end - start;
4000 if (length <= 0) {
4001 return empty_string();
4002 }
4003
4004 // Make an attempt to flatten the buffer to reduce access time.
4005 buffer = buffer->TryFlattenGetString();
4006
4007 if (length == 1) {
4008 return LookupSingleCharacterStringFromCode(buffer->Get(start));
4009 } else if (length == 2) {
4010 // Optimization for 2-byte strings often used as keys in a decompression
4011 // dictionary. Check whether we already have the string in the string
4012 // table to prevent creation of many unnecessary strings.
4013 uint16_t c1 = buffer->Get(start);
4014 uint16_t c2 = buffer->Get(start + 1);
4015 return MakeOrFindTwoCharacterString(this, c1, c2);
4016 }
4017
4018 if (!FLAG_string_slices ||
4019 !buffer->IsFlat() ||
4020 length < SlicedString::kMinLength ||
4021 pretenure == TENURED) {
4022 Object* result;
4023 // WriteToFlat takes care of the case when an indirect string has a
4024 // different encoding from its underlying string. These encodings may
4025 // differ because of externalization.
4026 bool is_one_byte = buffer->IsOneByteRepresentation();
4027 { MaybeObject* maybe_result = is_one_byte
4028 ? AllocateRawOneByteString(length, pretenure)
4029 : AllocateRawTwoByteString(length, pretenure);
4030 if (!maybe_result->ToObject(&result)) return maybe_result;
4031 }
4032 String* string_result = String::cast(result);
4033 // Copy the characters into the new object.
4034 if (is_one_byte) {
4035 ASSERT(string_result->IsOneByteRepresentation());
4036 uint8_t* dest = SeqOneByteString::cast(string_result)->GetChars();
4037 String::WriteToFlat(buffer, dest, start, end);
4038 } else {
4039 ASSERT(string_result->IsTwoByteRepresentation());
4040 uc16* dest = SeqTwoByteString::cast(string_result)->GetChars();
4041 String::WriteToFlat(buffer, dest, start, end);
4042 }
4043 return result;
4044 }
4045
4046 ASSERT(buffer->IsFlat());
4047 #if VERIFY_HEAP
4048 if (FLAG_verify_heap) {
4049 buffer->StringVerify();
4050 }
4051 #endif
4052
4053 Object* result;
4054 // When slicing an indirect string we use its encoding for a newly created
4055 // slice and don't check the encoding of the underlying string. This is safe
4056 // even if the encodings are different because of externalization. If an
4057 // indirect ASCII string is pointing to a two-byte string, the two-byte char
4058 // codes of the underlying string must still fit into ASCII (because
4059 // externalization must not change char codes).
4060 { Map* map = buffer->IsOneByteRepresentation()
4061 ? sliced_ascii_string_map()
4062 : sliced_string_map();
4063 MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
4064 if (!maybe_result->ToObject(&result)) return maybe_result;
4065 }
4066
4067 DisallowHeapAllocation no_gc;
4068 SlicedString* sliced_string = SlicedString::cast(result);
4069 sliced_string->set_length(length);
4070 sliced_string->set_hash_field(String::kEmptyHashField);
4071 if (buffer->IsConsString()) {
4072 ConsString* cons = ConsString::cast(buffer);
4073 ASSERT(cons->second()->length() == 0);
4074 sliced_string->set_parent(cons->first());
4075 sliced_string->set_offset(start);
4076 } else if (buffer->IsSlicedString()) {
4077 // Prevent nesting sliced strings.
4078 SlicedString* parent_slice = SlicedString::cast(buffer);
4079 sliced_string->set_parent(parent_slice->parent());
4080 sliced_string->set_offset(start + parent_slice->offset());
4081 } else {
4082 sliced_string->set_parent(buffer);
4083 sliced_string->set_offset(start);
4084 }
4085 ASSERT(sliced_string->parent()->IsSeqString() ||
4086 sliced_string->parent()->IsExternalString());
4087 return result;
4088 }
4089
4090
4091 MaybeObject* Heap::AllocateExternalStringFromAscii( 3843 MaybeObject* Heap::AllocateExternalStringFromAscii(
4092 const ExternalAsciiString::Resource* resource) { 3844 const ExternalAsciiString::Resource* resource) {
4093 size_t length = resource->length(); 3845 size_t length = resource->length();
4094 if (length > static_cast<size_t>(String::kMaxLength)) { 3846 if (length > static_cast<size_t>(String::kMaxLength)) {
4095 isolate()->context()->mark_out_of_memory(); 3847 isolate()->context()->mark_out_of_memory();
4096 return Failure::OutOfMemoryException(0x5); 3848 return Failure::OutOfMemoryException(0x5);
4097 } 3849 }
4098 3850
4099 Map* map = external_ascii_string_map(); 3851 Map* map = external_ascii_string_map();
4100 Object* result; 3852 Object* result;
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
4257 } 4009 }
4258 4010
4259 // Initialize the object 4011 // Initialize the object
4260 result->set_map_no_write_barrier(code_map()); 4012 result->set_map_no_write_barrier(code_map());
4261 Code* code = Code::cast(result); 4013 Code* code = Code::cast(result);
4262 ASSERT(!isolate_->code_range()->exists() || 4014 ASSERT(!isolate_->code_range()->exists() ||
4263 isolate_->code_range()->contains(code->address())); 4015 isolate_->code_range()->contains(code->address()));
4264 code->set_instruction_size(desc.instr_size); 4016 code->set_instruction_size(desc.instr_size);
4265 code->set_relocation_info(reloc_info); 4017 code->set_relocation_info(reloc_info);
4266 code->set_flags(flags); 4018 code->set_flags(flags);
4019 code->set_raw_kind_specific_flags1(0);
4020 code->set_raw_kind_specific_flags2(0);
4267 if (code->is_call_stub() || code->is_keyed_call_stub()) { 4021 if (code->is_call_stub() || code->is_keyed_call_stub()) {
4268 code->set_check_type(RECEIVER_MAP_CHECK); 4022 code->set_check_type(RECEIVER_MAP_CHECK);
4269 } 4023 }
4270 code->set_is_crankshafted(crankshafted); 4024 code->set_is_crankshafted(crankshafted);
4271 code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER); 4025 code->set_deoptimization_data(empty_fixed_array(), SKIP_WRITE_BARRIER);
4272 code->set_raw_type_feedback_info(undefined_value()); 4026 code->set_raw_type_feedback_info(undefined_value());
4273 code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER); 4027 code->set_handler_table(empty_fixed_array(), SKIP_WRITE_BARRIER);
4274 code->set_gc_metadata(Smi::FromInt(0)); 4028 code->set_gc_metadata(Smi::FromInt(0));
4275 code->set_ic_age(global_ic_age_); 4029 code->set_ic_age(global_ic_age_);
4276 code->set_prologue_offset(prologue_offset); 4030 code->set_prologue_offset(prologue_offset);
4277 if (code->kind() == Code::OPTIMIZED_FUNCTION) { 4031 if (code->kind() == Code::OPTIMIZED_FUNCTION) {
4278 code->set_marked_for_deoptimization(false); 4032 code->set_marked_for_deoptimization(false);
4279 } 4033 }
4034 code->set_constant_pool(empty_constant_pool_array());
4280 4035
4281 #ifdef ENABLE_DEBUGGER_SUPPORT 4036 #ifdef ENABLE_DEBUGGER_SUPPORT
4282 if (code->kind() == Code::FUNCTION) { 4037 if (code->kind() == Code::FUNCTION) {
4283 code->set_has_debug_break_slots( 4038 code->set_has_debug_break_slots(
4284 isolate_->debugger()->IsDebuggerActive()); 4039 isolate_->debugger()->IsDebuggerActive());
4285 } 4040 }
4286 #endif 4041 #endif
4287 4042
4288 // Allow self references to created code object by patching the handle to 4043 // Allow self references to created code object by patching the handle to
4289 // point to the newly allocated Code object. 4044 // point to the newly allocated Code object.
(...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after
5509 if (!maybe_object->To<HeapObject>(&object)) return maybe_object; 5264 if (!maybe_object->To<HeapObject>(&object)) return maybe_object;
5510 } 5265 }
5511 object = EnsureDoubleAligned(this, object, size); 5266 object = EnsureDoubleAligned(this, object, size);
5512 HeapObject::cast(object)->set_map_no_write_barrier(constant_pool_array_map()); 5267 HeapObject::cast(object)->set_map_no_write_barrier(constant_pool_array_map());
5513 5268
5514 ConstantPoolArray* constant_pool = 5269 ConstantPoolArray* constant_pool =
5515 reinterpret_cast<ConstantPoolArray*>(object); 5270 reinterpret_cast<ConstantPoolArray*>(object);
5516 constant_pool->SetEntryCounts(number_of_int64_entries, 5271 constant_pool->SetEntryCounts(number_of_int64_entries,
5517 number_of_ptr_entries, 5272 number_of_ptr_entries,
5518 number_of_int32_entries); 5273 number_of_int32_entries);
5519 MemsetPointer( 5274 if (number_of_ptr_entries > 0) {
5520 HeapObject::RawField( 5275 MemsetPointer(
5521 constant_pool, 5276 HeapObject::RawField(
5522 constant_pool->OffsetOfElementAt(constant_pool->first_ptr_index())), 5277 constant_pool,
5523 undefined_value(), 5278 constant_pool->OffsetOfElementAt(constant_pool->first_ptr_index())),
5524 number_of_ptr_entries); 5279 undefined_value(),
5280 number_of_ptr_entries);
5281 }
5525 return constant_pool; 5282 return constant_pool;
5526 } 5283 }
5527 5284
5528 5285
5286 MaybeObject* Heap::AllocateEmptyConstantPoolArray() {
5287 int size = ConstantPoolArray::SizeFor(0, 0, 0);
5288 Object* result;
5289 { MaybeObject* maybe_result =
5290 AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE);
5291 if (!maybe_result->ToObject(&result)) return maybe_result;
5292 }
5293 HeapObject::cast(result)->set_map_no_write_barrier(constant_pool_array_map());
5294 ConstantPoolArray::cast(result)->SetEntryCounts(0, 0, 0);
5295 return result;
5296 }
5297
5298
5529 MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) { 5299 MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) {
5530 Object* result; 5300 Object* result;
5531 { MaybeObject* maybe_result = AllocateFixedArray(length, pretenure); 5301 { MaybeObject* maybe_result = AllocateFixedArray(length, pretenure);
5532 if (!maybe_result->ToObject(&result)) return maybe_result; 5302 if (!maybe_result->ToObject(&result)) return maybe_result;
5533 } 5303 }
5534 reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier( 5304 reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier(
5535 hash_table_map()); 5305 hash_table_map());
5536 ASSERT(result->IsHashTable()); 5306 ASSERT(result->IsHashTable());
5537 return result; 5307 return result;
5538 } 5308 }
(...skipping 2243 matching lines...) Expand 10 before | Expand all | Expand 10 after
7782 #ifdef DEBUG 7552 #ifdef DEBUG
7783 void Heap::GarbageCollectionGreedyCheck() { 7553 void Heap::GarbageCollectionGreedyCheck() {
7784 ASSERT(FLAG_gc_greedy); 7554 ASSERT(FLAG_gc_greedy);
7785 if (isolate_->bootstrapper()->IsActive()) return; 7555 if (isolate_->bootstrapper()->IsActive()) return;
7786 if (disallow_allocation_failure()) return; 7556 if (disallow_allocation_failure()) return;
7787 CollectGarbage(NEW_SPACE); 7557 CollectGarbage(NEW_SPACE);
7788 } 7558 }
7789 #endif 7559 #endif
7790 7560
7791 7561
7792 TranscendentalCache::SubCache::SubCache(Isolate* isolate, Type t)
7793 : type_(t),
7794 isolate_(isolate) {
7795 uint32_t in0 = 0xffffffffu; // Bit-pattern for a NaN that isn't
7796 uint32_t in1 = 0xffffffffu; // generated by the FPU.
7797 for (int i = 0; i < kCacheSize; i++) {
7798 elements_[i].in[0] = in0;
7799 elements_[i].in[1] = in1;
7800 elements_[i].output = NULL;
7801 }
7802 }
7803
7804
7805 void TranscendentalCache::Clear() {
7806 for (int i = 0; i < kNumberOfCaches; i++) {
7807 if (caches_[i] != NULL) {
7808 delete caches_[i];
7809 caches_[i] = NULL;
7810 }
7811 }
7812 }
7813
7814
7815 void ExternalStringTable::CleanUp() { 7562 void ExternalStringTable::CleanUp() {
7816 int last = 0; 7563 int last = 0;
7817 for (int i = 0; i < new_space_strings_.length(); ++i) { 7564 for (int i = 0; i < new_space_strings_.length(); ++i) {
7818 if (new_space_strings_[i] == heap_->the_hole_value()) { 7565 if (new_space_strings_[i] == heap_->the_hole_value()) {
7819 continue; 7566 continue;
7820 } 7567 }
7821 ASSERT(new_space_strings_[i]->IsExternalString()); 7568 ASSERT(new_space_strings_[i]->IsExternalString());
7822 if (heap_->InNewSpace(new_space_strings_[i])) { 7569 if (heap_->InNewSpace(new_space_strings_[i])) {
7823 new_space_strings_[last++] = new_space_strings_[i]; 7570 new_space_strings_[last++] = new_space_strings_[i];
7824 } else { 7571 } else {
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
7993 static_cast<int>(object_sizes_last_time_[index])); 7740 static_cast<int>(object_sizes_last_time_[index]));
7994 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 7741 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
7995 #undef ADJUST_LAST_TIME_OBJECT_COUNT 7742 #undef ADJUST_LAST_TIME_OBJECT_COUNT
7996 7743
7997 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 7744 OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
7998 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 7745 OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
7999 ClearObjectStats(); 7746 ClearObjectStats();
8000 } 7747 }
8001 7748
8002 } } // namespace v8::internal 7749 } } // 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