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