Update V8 to r4588
We're using WebKit r58033, as used by
http://src.chromium.org/svn/releases/5.0.387.0/DEPS
This requires http://v8.googlecode.com/svn/trunk@4465 but this version has a
crashing bug for ARM. Instead we use http://v8.googlecode.com/svn/trunk@4588,
which is used by http://src.chromium.org/svn/releases/6.0.399.0/DEPS
Note that a trivial bug fix was required in arm/codegen-arm.cc. This is guarded
with ANDROID. See http://code.google.com/p/v8/issues/detail?id=703
Change-Id: I459647a8286c4f8c7405f0c5581ecbf051a6f1e8
diff --git a/src/heap.h b/src/heap.h
index b107318..902fc77 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -30,12 +30,15 @@
#include <math.h>
-#include "zone-inl.h"
-
+#include "splay-tree-inl.h"
+#include "v8-counters.h"
namespace v8 {
namespace internal {
+// Forward declarations.
+class ZoneScopeInfo;
+
// Defines all the roots in Heap.
#define UNCONDITIONAL_STRONG_ROOT_LIST(V) \
/* Put the byte array map early. We need it to be in place by the time */ \
@@ -86,7 +89,6 @@
V(Map, code_map, CodeMap) \
V(Map, oddball_map, OddballMap) \
V(Map, global_property_cell_map, GlobalPropertyCellMap) \
- V(Map, boilerplate_function_map, BoilerplateFunctionMap) \
V(Map, shared_function_info_map, SharedFunctionInfoMap) \
V(Map, proxy_map, ProxyMap) \
V(Object, nan_value, NanValue) \
@@ -108,7 +110,7 @@
V(Script, empty_script, EmptyScript) \
V(Smi, real_stack_limit, RealStackLimit) \
-#if V8_TARGET_ARCH_ARM && V8_NATIVE_REGEXP
+#if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP
#define STRONG_ROOT_LIST(V) \
UNCONDITIONAL_STRONG_ROOT_LIST(V) \
V(Code, re_c_entry_code, RegExpCEntryCode)
@@ -146,6 +148,13 @@
V(number_symbol, "number") \
V(Number_symbol, "Number") \
V(RegExp_symbol, "RegExp") \
+ V(source_symbol, "source") \
+ V(global_symbol, "global") \
+ V(ignore_case_symbol, "ignoreCase") \
+ V(multiline_symbol, "multiline") \
+ V(input_symbol, "input") \
+ V(index_symbol, "index") \
+ V(last_index_symbol, "lastIndex") \
V(object_symbol, "object") \
V(prototype_symbol, "prototype") \
V(string_symbol, "string") \
@@ -192,6 +201,9 @@
class HeapStats;
+typedef String* (*ExternalStringTableUpdaterCallback)(Object** pointer);
+
+
// The all static Heap captures the interface to the global object heap.
// All JavaScript contexts by this process share the same object heap.
@@ -346,6 +358,9 @@
// Allocate a map for the specified function
static Object* AllocateInitialMap(JSFunction* fun);
+ // Allocates an empty code cache.
+ static Object* AllocateCodeCache();
+
// Allocates and fully initializes a String. There are two String
// encodings: ASCII and two byte. One should choose between the three string
// allocation functions based on the encoding of the string buffer used to
@@ -450,9 +465,16 @@
// failed.
// Please note this does not perform a garbage collection.
static Object* AllocateFixedArray(int length, PretenureFlag pretenure);
- // Allocate uninitialized, non-tenured fixed array with length elements.
+ // Allocates a fixed array initialized with undefined values
static Object* AllocateFixedArray(int length);
+ // Allocates an uninitialized fixed array. It must be filled by the caller.
+ //
+ // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
+ // failed.
+ // Please note this does not perform a garbage collection.
+ static Object* AllocateUninitializedFixedArray(int length);
+
// Make a copy of src and return it. Returns
// Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
static Object* CopyFixedArray(FixedArray* src);
@@ -461,11 +483,14 @@
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed.
// Please note this does not perform a garbage collection.
- static Object* AllocateFixedArrayWithHoles(int length);
+ static Object* AllocateFixedArrayWithHoles(
+ int length,
+ PretenureFlag pretenure = NOT_TENURED);
// AllocateHashTable is identical to AllocateFixedArray except
// that the resulting object has hash_table_map as map.
- static Object* AllocateHashTable(int length);
+ static Object* AllocateHashTable(int length,
+ PretenureFlag pretenure = NOT_TENURED);
// Allocate a global (but otherwise uninitialized) context.
static Object* AllocateGlobalContext();
@@ -502,13 +527,6 @@
// Please note this does not perform a garbage collection.
static Object* AllocateArgumentsObject(Object* callee, int length);
- // Converts a double into either a Smi or a HeapNumber object.
- // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
- // failed.
- // Please note this does not perform a garbage collection.
- static Object* NewNumberFromDouble(double value,
- PretenureFlag pretenure = NOT_TENURED);
-
// Same as NewNumberFromDouble, but may return a preallocated/immutable
// number object (e.g., minus_zero_value_, nan_value_)
static Object* NumberFromDouble(double value,
@@ -557,7 +575,8 @@
// Please note this does not perform a garbage collection.
static Object* AllocateSubString(String* buffer,
int start,
- int end);
+ int end,
+ PretenureFlag pretenure = NOT_TENURED);
// Allocate a new external string object, which is backed by a string
// resource that resides outside the V8 heap.
@@ -598,6 +617,11 @@
Handle<Object> self_reference);
static Object* CopyCode(Code* code);
+
+ // Copy the code and scope info part of the code object, but insert
+ // the provided data as the relocation information.
+ static Object* CopyCode(Code* code, Vector<byte> reloc_info);
+
// Finds the symbol for string in the symbol table.
// If not found, a new symbol is added to the table and returned.
// Returns Failure::RetryAfterGC(requested_bytes, space) if allocation
@@ -615,6 +639,15 @@
// NULL is returned if string is in new space or not flattened.
static Map* SymbolMapForString(String* str);
+ // Tries to flatten a string before compare operation.
+ //
+ // Returns a failure in case it was decided that flattening was
+ // necessary and failed. Note, if flattening is not necessary the
+ // string might stay non-flat even when not a failure is returned.
+ //
+ // Please note this function does not perform a garbage collection.
+ static inline Object* PrepareForCompare(String* str);
+
// Converts the given boolean condition to JavaScript boolean value.
static Object* ToBoolean(bool condition) {
return condition ? true_value() : false_value();
@@ -633,12 +666,8 @@
// parameter is true.
static void CollectAllGarbage(bool force_compaction);
- // Performs a full garbage collection if a context has been disposed
- // since the last time the check was performed.
- static void CollectAllGarbageIfContextDisposed();
-
// Notify the heap that a context has been disposed.
- static void NotifyContextDisposed();
+ static int NotifyContextDisposed() { return ++contexts_disposed_; }
// Utility to invoke the scavenger. This is needed in test code to
// ensure correct callback for weak global handles.
@@ -649,10 +678,20 @@
static bool GarbageCollectionGreedyCheck();
#endif
+ static void AddGCPrologueCallback(
+ GCEpilogueCallback callback, GCType gc_type_filter);
+ static void RemoveGCPrologueCallback(GCEpilogueCallback callback);
+
+ static void AddGCEpilogueCallback(
+ GCEpilogueCallback callback, GCType gc_type_filter);
+ static void RemoveGCEpilogueCallback(GCEpilogueCallback callback);
+
static void SetGlobalGCPrologueCallback(GCCallback callback) {
+ ASSERT((callback == NULL) ^ (global_gc_prologue_callback_ == NULL));
global_gc_prologue_callback_ = callback;
}
static void SetGlobalGCEpilogueCallback(GCCallback callback) {
+ ASSERT((callback == NULL) ^ (global_gc_epilogue_callback_ == NULL));
global_gc_epilogue_callback_ = callback;
}
@@ -774,6 +813,9 @@
// Write barrier support for address[offset] = o.
static inline void RecordWrite(Address address, int offset);
+ // Write barrier support for address[start : start + len[ = o.
+ static inline void RecordWrites(Address address, int start, int len);
+
// Given an address occupied by a live code object, return that object.
static Object* FindCodeObject(Address a);
@@ -848,8 +890,10 @@
// Returns the adjusted value.
static inline int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes);
- // Allocate unitialized fixed array (pretenure == NON_TENURE).
+ // Allocate uninitialized fixed array.
static Object* AllocateRawFixedArray(int length);
+ static Object* AllocateRawFixedArray(int length,
+ PretenureFlag pretenure);
// True if we have reached the allocation limit in the old generation that
// should force the next GC (caused normally) to be a full one.
@@ -892,7 +936,8 @@
kRootListLength
};
- static Object* NumberToString(Object* number);
+ static Object* NumberToString(Object* number,
+ bool check_number_string_cache = true);
static Map* MapForExternalArrayType(ExternalArrayType array_type);
static RootListIndex RootIndexForExternalArrayType(
@@ -900,6 +945,32 @@
static void RecordStats(HeapStats* stats);
+ // Copy block of memory from src to dst. Size of block should be aligned
+ // by pointer size.
+ static inline void CopyBlock(Object** dst, Object** src, int byte_size);
+
+ // Optimized version of memmove for blocks with pointer size aligned sizes and
+ // pointer size aligned addresses.
+ static inline void MoveBlock(Object** dst, Object** src, int byte_size);
+
+ // Check new space expansion criteria and expand semispaces if it was hit.
+ static void CheckNewSpaceExpansionCriteria();
+
+ static inline void IncrementYoungSurvivorsCounter(int survived) {
+ survived_since_last_expansion_ += survived;
+ }
+
+ static void UpdateNewSpaceReferencesInExternalStringTable(
+ ExternalStringTableUpdaterCallback updater_func);
+
+ // Helper function that governs the promotion policy from new space to
+ // old. If the object's old address lies below the new space's age
+ // mark or if we've already filled the bottom 1/16th of the to space,
+ // we try to promote this object.
+ static inline bool ShouldBePromoted(Address old_address, int object_size);
+
+ static int MaxObjectSizeInNewSpace() { return kMaxObjectSizeInNewSpace; }
+
private:
static int reserved_semispace_size_;
static int max_semispace_size_;
@@ -913,7 +984,9 @@
static int always_allocate_scope_depth_;
static int linear_allocation_scope_depth_;
- static bool context_disposed_pending_;
+
+ // For keeping track of context disposals.
+ static int contexts_disposed_;
#if defined(V8_TARGET_ARCH_X64)
static const int kMaxObjectSizeInNewSpace = 512*KB;
@@ -939,6 +1012,9 @@
static int mc_count_; // how many mark-compact collections happened
static int gc_count_; // how many gc happened
+ // Total length of the strings we failed to flatten since the last GC.
+ static int unflattened_strings_length_;
+
#define ROOT_ACCESSOR(type, name, camel_name) \
static inline void set_##name(type* value) { \
roots_[k##camel_name##RootIndex] = value; \
@@ -1013,6 +1089,30 @@
// GC callback function, called before and after mark-compact GC.
// Allocations in the callback function are disallowed.
+ struct GCPrologueCallbackPair {
+ GCPrologueCallbackPair(GCPrologueCallback callback, GCType gc_type)
+ : callback(callback), gc_type(gc_type) {
+ }
+ bool operator==(const GCPrologueCallbackPair& pair) const {
+ return pair.callback == callback;
+ }
+ GCPrologueCallback callback;
+ GCType gc_type;
+ };
+ static List<GCPrologueCallbackPair> gc_prologue_callbacks_;
+
+ struct GCEpilogueCallbackPair {
+ GCEpilogueCallbackPair(GCEpilogueCallback callback, GCType gc_type)
+ : callback(callback), gc_type(gc_type) {
+ }
+ bool operator==(const GCEpilogueCallbackPair& pair) const {
+ return pair.callback == callback;
+ }
+ GCEpilogueCallback callback;
+ GCType gc_type;
+ };
+ static List<GCEpilogueCallbackPair> gc_epilogue_callbacks_;
+
static GCCallback global_gc_prologue_callback_;
static GCCallback global_gc_epilogue_callback_;
@@ -1024,12 +1124,6 @@
GarbageCollector collector,
GCTracer* tracer);
- // Returns either a Smi or a Number object from 'value'. If 'new_object'
- // is false, it may return a preallocated immutable object.
- static Object* SmiOrNumberFromDouble(double value,
- bool new_object,
- PretenureFlag pretenure = NOT_TENURED);
-
// Allocate an uninitialized object in map space. The behavior is identical
// to Heap::AllocateRaw(size_in_bytes, MAP_SPACE), except that (a) it doesn't
// have to test the allocation space argument and (b) can reduce code size
@@ -1056,16 +1150,17 @@
static void CreateFixedStubs();
- static Object* CreateOddball(Map* map,
- const char* to_string,
- Object* to_number);
+ static Object* CreateOddball(const char* to_string, Object* to_number);
// Allocate empty fixed array.
static Object* AllocateEmptyFixedArray();
// Performs a minor collection in new generation.
static void Scavenge();
- static void ScavengeExternalStringTable();
+
+ static String* UpdateNewSpaceReferenceInExternalStringTableEntry(
+ Object** pointer);
+
static Address DoScavenge(ObjectVisitor* scavenge_visitor,
Address new_space_front);
@@ -1083,11 +1178,8 @@
HeapObject* target,
int size);
- // Helper function that governs the promotion policy from new space to
- // old. If the object's old address lies below the new space's age
- // mark or if we've already filled the bottom 1/16th of the to space,
- // we try to promote this object.
- static inline bool ShouldBePromoted(Address old_address, int object_size);
+ static void ClearJSFunctionResultCaches();
+
#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
// Record the copy of an object in the NewSpace's statistics.
static void RecordCopiedObject(HeapObject* obj);
@@ -1106,9 +1198,6 @@
// Slow part of scavenge object.
static void ScavengeObjectSlow(HeapObject** p, HeapObject* object);
- // Copy memory from src to dst.
- static inline void CopyBlock(Object** dst, Object** src, int byte_size);
-
// Initializes a function with a shared part and prototype.
// Returns the function.
// Note: this code was factored out of AllocateFunction such that
@@ -1137,26 +1226,26 @@
class HeapStats {
public:
- int *start_marker;
- int *new_space_size;
- int *new_space_capacity;
- int *old_pointer_space_size;
- int *old_pointer_space_capacity;
- int *old_data_space_size;
- int *old_data_space_capacity;
- int *code_space_size;
- int *code_space_capacity;
- int *map_space_size;
- int *map_space_capacity;
- int *cell_space_size;
- int *cell_space_capacity;
- int *lo_space_size;
- int *global_handle_count;
- int *weak_global_handle_count;
- int *pending_global_handle_count;
- int *near_death_global_handle_count;
- int *destroyed_global_handle_count;
- int *end_marker;
+ int* start_marker;
+ int* new_space_size;
+ int* new_space_capacity;
+ int* old_pointer_space_size;
+ int* old_pointer_space_capacity;
+ int* old_data_space_size;
+ int* old_data_space_capacity;
+ int* code_space_size;
+ int* code_space_capacity;
+ int* map_space_size;
+ int* map_space_capacity;
+ int* cell_space_size;
+ int* cell_space_capacity;
+ int* lo_space_size;
+ int* global_handle_count;
+ int* weak_global_handle_count;
+ int* pending_global_handle_count;
+ int* near_death_global_handle_count;
+ int* destroyed_global_handle_count;
+ int* end_marker;
};
@@ -1525,8 +1614,23 @@
class GCTracer BASE_EMBEDDED {
public:
- GCTracer();
+ // Time spent while in the external scope counts towards the
+ // external time in the tracer and will be reported separately.
+ class ExternalScope BASE_EMBEDDED {
+ public:
+ explicit ExternalScope(GCTracer* tracer) : tracer_(tracer) {
+ start_time_ = OS::TimeCurrentMillis();
+ }
+ ~ExternalScope() {
+ tracer_->external_time_ += OS::TimeCurrentMillis() - start_time_;
+ }
+ private:
+ GCTracer* tracer_;
+ double start_time_;
+ };
+
+ GCTracer();
~GCTracer();
// Sets the collector.
@@ -1540,6 +1644,7 @@
// Sets the flag that this is a compacting full GC.
void set_is_compacting() { is_compacting_ = true; }
+ bool is_compacting() const { return is_compacting_; }
// Increment and decrement the count of marked objects.
void increment_marked_count() { ++marked_count_; }
@@ -1560,6 +1665,9 @@
double start_size_; // Size of objects in heap set in constructor.
GarbageCollector collector_; // Type of collector.
+ // Keep track of the amount of time spent in external callbacks.
+ double external_time_;
+
// A count (including this one, eg, the first collection is 1) of the
// number of garbage collections.
int gc_count_;