Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE
This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.
FPIIM-449
Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/src/heap/heap.h b/src/heap/heap.h
index af9d0a6..4a76777 100644
--- a/src/heap/heap.h
+++ b/src/heap/heap.h
@@ -14,6 +14,7 @@
#include "src/assert-scope.h"
#include "src/atomic-utils.h"
#include "src/globals.h"
+#include "src/heap-symbols.h"
// TODO(mstarzinger): Two more includes to kill!
#include "src/heap/spaces.h"
#include "src/heap/store-buffer.h"
@@ -36,7 +37,6 @@
V(Oddball, true_value, TrueValue) \
V(Oddball, false_value, FalseValue) \
V(String, empty_string, empty_string) \
- V(String, hidden_string, hidden_string) \
V(Oddball, uninitialized_value, UninitializedValue) \
V(Map, cell_map, CellMap) \
V(Map, global_property_cell_map, GlobalPropertyCellMap) \
@@ -187,11 +187,9 @@
V(PropertyCell, empty_property_cell, EmptyPropertyCell) \
V(Object, weak_stack_trace_list, WeakStackTraceList) \
V(Object, noscript_shared_function_infos, NoScriptSharedFunctionInfos) \
- V(FixedArray, interpreter_table, InterpreterTable) \
V(Map, bytecode_array_map, BytecodeArrayMap) \
V(WeakCell, empty_weak_cell, EmptyWeakCell) \
- V(BytecodeArray, empty_bytecode_array, EmptyBytecodeArray)
-
+ V(PropertyCell, species_protector, SpeciesProtector)
// Entries in this list are limited to Smis and are not visited during GC.
#define SMI_ROOT_LIST(V) \
@@ -209,196 +207,6 @@
SMI_ROOT_LIST(V) \
V(StringTable, string_table, StringTable)
-#define INTERNALIZED_STRING_LIST(V) \
- V(anonymous_string, "anonymous") \
- V(apply_string, "apply") \
- V(assign_string, "assign") \
- V(arguments_string, "arguments") \
- V(Arguments_string, "Arguments") \
- V(Array_string, "Array") \
- V(bind_string, "bind") \
- V(bool16x8_string, "bool16x8") \
- V(Bool16x8_string, "Bool16x8") \
- V(bool32x4_string, "bool32x4") \
- V(Bool32x4_string, "Bool32x4") \
- V(bool8x16_string, "bool8x16") \
- V(Bool8x16_string, "Bool8x16") \
- V(boolean_string, "boolean") \
- V(Boolean_string, "Boolean") \
- V(bound__string, "bound ") \
- V(byte_length_string, "byteLength") \
- V(byte_offset_string, "byteOffset") \
- V(call_string, "call") \
- V(callee_string, "callee") \
- V(caller_string, "caller") \
- V(cell_value_string, "%cell_value") \
- V(char_at_string, "CharAt") \
- V(closure_string, "(closure)") \
- V(compare_ic_string, "==") \
- V(configurable_string, "configurable") \
- V(constructor_string, "constructor") \
- V(construct_string, "construct") \
- V(create_string, "create") \
- V(Date_string, "Date") \
- V(default_string, "default") \
- V(defineProperty_string, "defineProperty") \
- V(deleteProperty_string, "deleteProperty") \
- V(display_name_string, "displayName") \
- V(done_string, "done") \
- V(dot_result_string, ".result") \
- V(dot_string, ".") \
- V(enumerable_string, "enumerable") \
- V(enumerate_string, "enumerate") \
- V(Error_string, "Error") \
- V(eval_string, "eval") \
- V(false_string, "false") \
- V(float32x4_string, "float32x4") \
- V(Float32x4_string, "Float32x4") \
- V(for_api_string, "for_api") \
- V(for_string, "for") \
- V(function_string, "function") \
- V(Function_string, "Function") \
- V(Generator_string, "Generator") \
- V(getOwnPropertyDescriptor_string, "getOwnPropertyDescriptor") \
- V(getPrototypeOf_string, "getPrototypeOf") \
- V(get_string, "get") \
- V(global_string, "global") \
- V(has_string, "has") \
- V(illegal_access_string, "illegal access") \
- V(illegal_argument_string, "illegal argument") \
- V(index_string, "index") \
- V(infinity_string, "Infinity") \
- V(input_string, "input") \
- V(int16x8_string, "int16x8") \
- V(Int16x8_string, "Int16x8") \
- V(int32x4_string, "int32x4") \
- V(Int32x4_string, "Int32x4") \
- V(int8x16_string, "int8x16") \
- V(Int8x16_string, "Int8x16") \
- V(isExtensible_string, "isExtensible") \
- V(isView_string, "isView") \
- V(KeyedLoadMonomorphic_string, "KeyedLoadMonomorphic") \
- V(KeyedStoreMonomorphic_string, "KeyedStoreMonomorphic") \
- V(last_index_string, "lastIndex") \
- V(length_string, "length") \
- V(Map_string, "Map") \
- V(minus_infinity_string, "-Infinity") \
- V(minus_zero_string, "-0") \
- V(name_string, "name") \
- V(nan_string, "NaN") \
- V(next_string, "next") \
- V(null_string, "null") \
- V(null_to_string, "[object Null]") \
- V(number_string, "number") \
- V(Number_string, "Number") \
- V(object_string, "object") \
- V(Object_string, "Object") \
- V(ownKeys_string, "ownKeys") \
- V(preventExtensions_string, "preventExtensions") \
- V(private_api_string, "private_api") \
- V(Promise_string, "Promise") \
- V(proto_string, "__proto__") \
- V(prototype_string, "prototype") \
- V(Proxy_string, "Proxy") \
- V(query_colon_string, "(?:)") \
- V(RegExp_string, "RegExp") \
- V(setPrototypeOf_string, "setPrototypeOf") \
- V(set_string, "set") \
- V(Set_string, "Set") \
- V(source_mapping_url_string, "source_mapping_url") \
- V(source_string, "source") \
- V(source_url_string, "source_url") \
- V(stack_string, "stack") \
- V(strict_compare_ic_string, "===") \
- V(string_string, "string") \
- V(String_string, "String") \
- V(symbol_string, "symbol") \
- V(Symbol_string, "Symbol") \
- V(this_string, "this") \
- V(throw_string, "throw") \
- V(toJSON_string, "toJSON") \
- V(toString_string, "toString") \
- V(true_string, "true") \
- V(uint16x8_string, "uint16x8") \
- V(Uint16x8_string, "Uint16x8") \
- V(uint32x4_string, "uint32x4") \
- V(Uint32x4_string, "Uint32x4") \
- V(uint8x16_string, "uint8x16") \
- V(Uint8x16_string, "Uint8x16") \
- V(undefined_string, "undefined") \
- V(undefined_to_string, "[object Undefined]") \
- V(valueOf_string, "valueOf") \
- V(value_string, "value") \
- V(WeakMap_string, "WeakMap") \
- V(WeakSet_string, "WeakSet") \
- V(writable_string, "writable")
-
-#define PRIVATE_SYMBOL_LIST(V) \
- V(array_iteration_kind_symbol) \
- V(array_iterator_next_symbol) \
- V(array_iterator_object_symbol) \
- V(call_site_function_symbol) \
- V(call_site_position_symbol) \
- V(call_site_receiver_symbol) \
- V(call_site_strict_symbol) \
- V(class_end_position_symbol) \
- V(class_start_position_symbol) \
- V(detailed_stack_trace_symbol) \
- V(elements_transition_symbol) \
- V(error_end_pos_symbol) \
- V(error_script_symbol) \
- V(error_start_pos_symbol) \
- V(formatted_stack_trace_symbol) \
- V(frozen_symbol) \
- V(hash_code_symbol) \
- V(home_object_symbol) \
- V(internal_error_symbol) \
- V(intl_impl_object_symbol) \
- V(intl_initialized_marker_symbol) \
- V(intl_pattern_symbol) \
- V(intl_resolved_symbol) \
- V(megamorphic_symbol) \
- V(native_context_index_symbol) \
- V(nonexistent_symbol) \
- V(nonextensible_symbol) \
- V(normal_ic_symbol) \
- V(not_mapped_symbol) \
- V(observed_symbol) \
- V(premonomorphic_symbol) \
- V(promise_combined_deferred_symbol) \
- V(promise_debug_marker_symbol) \
- V(promise_has_handler_symbol) \
- V(promise_on_resolve_symbol) \
- V(promise_on_reject_symbol) \
- V(promise_raw_symbol) \
- V(promise_status_symbol) \
- V(promise_value_symbol) \
- V(sealed_symbol) \
- V(stack_trace_symbol) \
- V(strict_function_transition_symbol) \
- V(string_iterator_iterated_string_symbol) \
- V(string_iterator_next_index_symbol) \
- V(strong_function_transition_symbol) \
- V(uninitialized_symbol)
-
-#define PUBLIC_SYMBOL_LIST(V) \
- V(has_instance_symbol, Symbol.hasInstance) \
- V(iterator_symbol, Symbol.iterator) \
- V(match_symbol, Symbol.match) \
- V(replace_symbol, Symbol.replace) \
- V(search_symbol, Symbol.search) \
- V(species_symbol, Symbol.species) \
- V(split_symbol, Symbol.split) \
- V(to_primitive_symbol, Symbol.toPrimitive) \
- V(unscopables_symbol, Symbol.unscopables)
-
-// Well-Known Symbols are "Public" symbols, which have a bit set which causes
-// them to produce an undefined value when a load results in a failed access
-// check. Because this behaviour is not specified properly as of yet, it only
-// applies to a subset of spec-defined Well-Known Symbols.
-#define WELL_KNOWN_SYMBOL_LIST(V) \
- V(is_concat_spreadable_symbol, Symbol.isConcatSpreadable) \
- V(to_string_tag_symbol, Symbol.toStringTag)
// Heap roots that are known to be immortal immovable, for which we can safely
// skip write barriers. This list is not complete and has omissions.
@@ -443,7 +251,6 @@
V(OrderedHashTableMap) \
V(EmptyFixedArray) \
V(EmptyByteArray) \
- V(EmptyBytecodeArray) \
V(EmptyDescriptorArray) \
V(ArgumentsMarker) \
V(SymbolMap) \
@@ -468,6 +275,7 @@
PRIVATE_SYMBOL_LIST(V)
// Forward declarations.
+class AllocationObserver;
class ArrayBufferTracker;
class GCIdleTimeAction;
class GCIdleTimeHandler;
@@ -483,6 +291,7 @@
class ScavengeJob;
class WeakObjectRetainer;
+typedef void (*ObjectSlotCallback)(HeapObject** from, HeapObject* to);
// A queue of objects promoted during scavenge. Each object is accompanied
// by it's size to avoid dereferencing a map pointer for scanning.
@@ -630,15 +439,17 @@
kSmiRootsStart = kStringTableRootIndex + 1
};
+ enum FindMementoMode { kForRuntime, kForGC };
+
+ enum HeapState { NOT_IN_GC, SCAVENGE, MARK_COMPACT };
+
// Indicates whether live bytes adjustment is triggered
// - from within the GC code before sweeping started (SEQUENTIAL_TO_SWEEPER),
// - or from within GC (CONCURRENT_TO_SWEEPER),
// - or mutator code (CONCURRENT_TO_SWEEPER).
enum InvocationMode { SEQUENTIAL_TO_SWEEPER, CONCURRENT_TO_SWEEPER };
- enum PretenuringFeedbackInsertionMode { kCached, kGlobal };
-
- enum HeapState { NOT_IN_GC, SCAVENGE, MARK_COMPACT };
+ enum UpdateAllocationSiteMode { kGlobal, kCached };
// Taking this lock prevents the GC from entering a phase that relocates
// object references.
@@ -709,20 +520,6 @@
static const double kMaxHeapGrowingFactorIdle;
static const double kTargetMutatorUtilization;
- // Sloppy mode arguments object size.
- static const int kSloppyArgumentsObjectSize =
- JSObject::kHeaderSize + 2 * kPointerSize;
-
- // Strict mode arguments has no callee so it is smaller.
- static const int kStrictArgumentsObjectSize =
- JSObject::kHeaderSize + 1 * kPointerSize;
-
- // Indicies for direct access into argument objects.
- static const int kArgumentsLengthIndex = 0;
-
- // callee is only valid in sloppy mode.
- static const int kArgumentsCalleeIndex = 1;
-
static const int kNoGCFlags = 0;
static const int kReduceMemoryFootprintMask = 1;
static const int kAbortIncrementalMarkingMask = 2;
@@ -860,20 +657,6 @@
// Notify the heap that a context has been disposed.
int NotifyContextDisposed(bool dependant_context);
- inline void increment_scan_on_scavenge_pages() {
- scan_on_scavenge_pages_++;
- if (FLAG_gc_verbose) {
- PrintF("Scan-on-scavenge pages: %d\n", scan_on_scavenge_pages_);
- }
- }
-
- inline void decrement_scan_on_scavenge_pages() {
- scan_on_scavenge_pages_--;
- if (FLAG_gc_verbose) {
- PrintF("Scan-on-scavenge pages: %d\n", scan_on_scavenge_pages_);
- }
- }
-
void set_native_contexts_list(Object* object) {
native_contexts_list_ = object;
}
@@ -927,6 +710,7 @@
// If an object has an AllocationMemento trailing it, return it, otherwise
// return NULL;
+ template <FindMementoMode mode>
inline AllocationMemento* FindAllocationMemento(HeapObject* object);
// Returns false if not able to reserve.
@@ -972,7 +756,6 @@
inline bool OldGenerationAllocationLimitReached();
void QueueMemoryChunkForFree(MemoryChunk* chunk);
- void FilterStoreBufferEntriesOnAboutToBeFreedPages();
void FreeQueuedChunks(MemoryChunk* list_head);
void FreeQueuedChunks();
void WaitUntilUnmappingOfFreeChunksCompleted();
@@ -1039,7 +822,7 @@
bool HasHighFragmentation(intptr_t used, intptr_t committed);
void SetOptimizeForLatency() { optimize_for_memory_usage_ = false; }
- void SetOptimizeForMemoryUsage() { optimize_for_memory_usage_ = true; }
+ void SetOptimizeForMemoryUsage();
bool ShouldOptimizeForMemoryUsage() { return optimize_for_memory_usage_; }
// ===========================================================================
@@ -1074,7 +857,6 @@
// address with the mask will result in the start address of the new space
// for all addresses in either semispace.
Address NewSpaceStart() { return new_space_.start(); }
- uintptr_t NewSpaceMask() { return new_space_.mask(); }
Address NewSpaceTop() { return new_space_.top(); }
NewSpace* new_space() { return &new_space_; }
@@ -1270,16 +1052,16 @@
// Store buffer API. =========================================================
// ===========================================================================
- // Write barrier support for address[offset] = o.
- INLINE(void RecordWrite(Address address, int offset));
-
- // Write barrier support for address[start : start + len[ = o.
- INLINE(void RecordWrites(Address address, int start, int len));
+ // Write barrier support for object[offset] = o;
+ inline void RecordWrite(Object* object, int offset, Object* o);
Address* store_buffer_top_address() {
return reinterpret_cast<Address*>(&roots_[kStoreBufferTopRootIndex]);
}
+ void ClearRecordedSlot(HeapObject* object, Object** slot);
+ void ClearRecordedSlotRange(HeapObject* object, Object** start, Object** end);
+
// ===========================================================================
// Incremental marking API. ==================================================
// ===========================================================================
@@ -1318,25 +1100,27 @@
// Returns whether the object resides in new space.
inline bool InNewSpace(Object* object);
- inline bool InNewSpace(Address address);
- inline bool InNewSpacePage(Address address);
inline bool InFromSpace(Object* object);
inline bool InToSpace(Object* object);
// Returns whether the object resides in old space.
- inline bool InOldSpace(Address address);
inline bool InOldSpace(Object* object);
// Checks whether an address/object in the heap (including auxiliary
// area and unused area).
- bool Contains(Address addr);
bool Contains(HeapObject* value);
// Checks whether an address/object in a space.
// Currently used by tests, serialization and heap verification only.
- bool InSpace(Address addr, AllocationSpace space);
bool InSpace(HeapObject* value, AllocationSpace space);
+ // Slow methods that can be used for verification as they can also be used
+ // with off-heap Addresses.
+ bool ContainsSlow(Address addr);
+ bool InSpaceSlow(Address addr, AllocationSpace space);
+ inline bool InNewSpaceSlow(Address address);
+ inline bool InOldSpaceSlow(Address address);
+
// ===========================================================================
// Object statistics tracking. ===============================================
// ===========================================================================
@@ -1371,7 +1155,6 @@
int MaxSemiSpaceSize() { return max_semi_space_size_; }
int ReservedSemiSpaceSize() { return reserved_semispace_size_; }
int InitialSemiSpaceSize() { return initial_semispace_size_; }
- int TargetSemiSpaceSize() { return target_semispace_size_; }
intptr_t MaxOldGenerationSize() { return max_old_generation_size_; }
intptr_t MaxExecutableSize() { return max_executable_size_; }
@@ -1408,13 +1191,13 @@
void UpdateSurvivalStatistics(int start_new_space_size);
- inline void IncrementPromotedObjectsSize(int object_size) {
+ inline void IncrementPromotedObjectsSize(intptr_t object_size) {
DCHECK_GE(object_size, 0);
promoted_objects_size_ += object_size;
}
inline intptr_t promoted_objects_size() { return promoted_objects_size_; }
- inline void IncrementSemiSpaceCopiedObjectSize(int object_size) {
+ inline void IncrementSemiSpaceCopiedObjectSize(intptr_t object_size) {
DCHECK_GE(object_size, 0);
semi_space_copied_object_size_ += object_size;
}
@@ -1432,8 +1215,8 @@
inline void IncrementNodesPromoted() { nodes_promoted_++; }
- inline void IncrementYoungSurvivorsCounter(int survived) {
- DCHECK(survived >= 0);
+ inline void IncrementYoungSurvivorsCounter(intptr_t survived) {
+ DCHECK_GE(survived, 0);
survived_last_scavenge_ = survived;
survived_since_last_expansion_ += survived;
}
@@ -1547,6 +1330,7 @@
// the corresponding allocation site is immediately updated and an entry
// in the hash map is created. Otherwise the entry (including a the count
// value) is cached on the local pretenuring feedback.
+ template <UpdateAllocationSiteMode mode>
inline void UpdateAllocationSite(HeapObject* object,
HashMap* pretenuring_feedback);
@@ -1580,6 +1364,9 @@
void ReportHeapStatistics(const char* title);
void ReportCodeStatistics(const char* title);
#endif
+#ifdef ENABLE_SLOW_DCHECKS
+ int CountHandlesForObject(Object* object);
+#endif
private:
class PretenuringScope;
@@ -1684,9 +1471,6 @@
static String* UpdateNewSpaceReferenceInExternalStringTableEntry(
Heap* heap, Object** pointer);
- static void ScavengeStoreBufferCallback(Heap* heap, MemoryChunk* page,
- StoreBufferEvent event);
-
// Selects the proper allocation space based on the pretenuring decision.
static AllocationSpace SelectSpace(PretenureFlag pretenure) {
return (pretenure == TENURED) ? OLD_SPACE : NEW_SPACE;
@@ -2007,6 +1791,9 @@
MUST_USE_RESULT AllocationResult CopyCode(Code* code);
+ MUST_USE_RESULT AllocationResult
+ CopyBytecodeArray(BytecodeArray* bytecode_array);
+
// Allocates a fixed array initialized with undefined values
MUST_USE_RESULT AllocationResult
AllocateFixedArray(int length, PretenureFlag pretenure = NOT_TENURED);
@@ -2084,6 +1871,11 @@
MUST_USE_RESULT AllocationResult
CopyFixedArrayAndGrow(FixedArray* src, int grow_by, PretenureFlag pretenure);
+ // Make a copy of src, also grow the copy, and return the copy.
+ MUST_USE_RESULT AllocationResult CopyFixedArrayUpTo(FixedArray* src,
+ int new_len,
+ PretenureFlag pretenure);
+
// Make a copy of src, set the map, and return the copy.
MUST_USE_RESULT AllocationResult
CopyFixedArrayWithMap(FixedArray* src, Map* map);
@@ -2182,10 +1974,10 @@
// For keeping track of how much data has survived
// scavenge since last new space expansion.
- int survived_since_last_expansion_;
+ intptr_t survived_since_last_expansion_;
// ... and since the last scavenge.
- int survived_last_scavenge_;
+ intptr_t survived_last_scavenge_;
// This is not the depth of nested AlwaysAllocateScope's but rather a single
// count, as scopes can be acquired from multiple tasks (read: threads).
@@ -2201,8 +1993,6 @@
int global_ic_age_;
- int scan_on_scavenge_pages_;
-
NewSpace new_space_;
OldSpace* old_space_;
OldSpace* code_space_;
@@ -2270,8 +2060,6 @@
Object* encountered_transition_arrays_;
- StoreBufferRebuilder store_buffer_rebuilder_;
-
List<GCCallbackPair> gc_epilogue_callbacks_;
List<GCCallbackPair> gc_prologue_callbacks_;
@@ -2339,7 +2127,7 @@
ScavengeJob* scavenge_job_;
- InlineAllocationObserver* idle_scavenge_observer_;
+ AllocationObserver* idle_scavenge_observer_;
// These two counters are monotomically increasing and never reset.
size_t full_codegen_bytes_generated_;
@@ -2696,16 +2484,7 @@
}
}
- static int Hash(Object* source, Name* name) {
- // Uses only lower 32 bits if pointers are larger.
- uint32_t source_hash =
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(source)) >>
- kPointerSizeLog2;
- uint32_t name_hash =
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name)) >>
- kPointerSizeLog2;
- return (source_hash ^ name_hash) % kLength;
- }
+ static inline int Hash(Object* source, Name* name);
static const int kLength = 64;
struct Key {
@@ -2790,6 +2569,61 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer);
};
#endif // DEBUG
+
+// -----------------------------------------------------------------------------
+// Allows observation of allocations.
+class AllocationObserver {
+ public:
+ explicit AllocationObserver(intptr_t step_size)
+ : step_size_(step_size), bytes_to_next_step_(step_size) {
+ DCHECK(step_size >= kPointerSize);
+ }
+ virtual ~AllocationObserver() {}
+
+ // Called each time the observed space does an allocation step. This may be
+ // more frequently than the step_size we are monitoring (e.g. when there are
+ // multiple observers, or when page or space boundary is encountered.)
+ void AllocationStep(int bytes_allocated, Address soon_object, size_t size) {
+ bytes_to_next_step_ -= bytes_allocated;
+ if (bytes_to_next_step_ <= 0) {
+ Step(static_cast<int>(step_size_ - bytes_to_next_step_), soon_object,
+ size);
+ step_size_ = GetNextStepSize();
+ bytes_to_next_step_ = step_size_;
+ }
+ }
+
+ protected:
+ intptr_t step_size() const { return step_size_; }
+ intptr_t bytes_to_next_step() const { return bytes_to_next_step_; }
+
+ // Pure virtual method provided by the subclasses that gets called when at
+ // least step_size bytes have been allocated. soon_object is the address just
+ // allocated (but not yet initialized.) size is the size of the object as
+ // requested (i.e. w/o the alignment fillers). Some complexities to be aware
+ // of:
+ // 1) soon_object will be nullptr in cases where we end up observing an
+ // allocation that happens to be a filler space (e.g. page boundaries.)
+ // 2) size is the requested size at the time of allocation. Right-trimming
+ // may change the object size dynamically.
+ // 3) soon_object may actually be the first object in an allocation-folding
+ // group. In such a case size is the size of the group rather than the
+ // first object.
+ virtual void Step(int bytes_allocated, Address soon_object, size_t size) = 0;
+
+ // Subclasses can override this method to make step size dynamic.
+ virtual intptr_t GetNextStepSize() { return step_size_; }
+
+ intptr_t step_size_;
+ intptr_t bytes_to_next_step_;
+
+ private:
+ friend class LargeObjectSpace;
+ friend class NewSpace;
+ friend class PagedSpace;
+ DISALLOW_COPY_AND_ASSIGN(AllocationObserver);
+};
+
} // namespace internal
} // namespace v8