summaryrefslogtreecommitdiff
path: root/deps/v8/src/objects.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/objects.h')
-rw-r--r--deps/v8/src/objects.h906
1 files changed, 520 insertions, 386 deletions
diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h
index 18e388f991..701712be32 100644
--- a/deps/v8/src/objects.h
+++ b/deps/v8/src/objects.h
@@ -97,7 +97,7 @@
// - ExternalFloatArray
// - String
// - SeqString
-// - SeqAsciiString
+// - SeqOneByteString
// - SeqTwoByteString
// - SlicedString
// - ConsString
@@ -178,6 +178,35 @@ enum TransitionFlag {
};
+// Indicates whether the transition is simple: the target map of the transition
+// either extends the current map with a new property, or it modifies the
+// property that was added last to the current map.
+enum SimpleTransitionFlag {
+ SIMPLE_TRANSITION,
+ FULL_TRANSITION
+};
+
+
+// Indicates whether we are only interested in the descriptors of a particular
+// map, or in all descriptors in the descriptor array.
+enum DescriptorFlag {
+ ALL_DESCRIPTORS,
+ OWN_DESCRIPTORS
+};
+
+// The GC maintains a bit of information, the MarkingParity, which toggles
+// from odd to even and back every time marking is completed. Incremental
+// marking can visit an object twice during a marking phase, so algorithms that
+// that piggy-back on marking can use the parity to ensure that they only
+// perform an operation on an object once per marking phase: they record the
+// MarkingParity when they visit an object, and only re-visit the object when it
+// is marked again and the MarkingParity changes.
+enum MarkingParity {
+ NO_MARKING_PARITY,
+ ODD_MARKING_PARITY,
+ EVEN_MARKING_PARITY
+};
+
// Instance size sentinel for objects of variable size.
const int kVariableSizeSentinel = 0;
@@ -450,7 +479,7 @@ const uint32_t kSymbolTag = 0x40;
// two-byte characters or one-byte characters.
const uint32_t kStringEncodingMask = 0x4;
const uint32_t kTwoByteStringTag = 0x0;
-const uint32_t kAsciiStringTag = 0x4;
+const uint32_t kOneByteStringTag = 0x4;
// If bit 7 is clear, the low-order 2 bits indicate the representation
// of the string.
@@ -501,39 +530,46 @@ const uint32_t kShortcutTypeTag = kConsStringTag;
enum InstanceType {
// String types.
SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kSeqStringTag,
- ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kSeqStringTag,
+ ASCII_SYMBOL_TYPE = kOneByteStringTag | kAsciiDataHintTag | kSymbolTag |
+ kSeqStringTag,
CONS_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kConsStringTag,
- CONS_ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kConsStringTag,
+ CONS_ASCII_SYMBOL_TYPE = kOneByteStringTag | kAsciiDataHintTag | kSymbolTag |
+ kConsStringTag,
SHORT_EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag |
kExternalStringTag | kShortExternalStringTag,
SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE =
kTwoByteStringTag | kSymbolTag | kExternalStringTag |
kAsciiDataHintTag | kShortExternalStringTag,
- SHORT_EXTERNAL_ASCII_SYMBOL_TYPE = kAsciiStringTag | kExternalStringTag |
- kSymbolTag | kShortExternalStringTag,
+ SHORT_EXTERNAL_ASCII_SYMBOL_TYPE = kOneByteStringTag | kAsciiDataHintTag |
+ kExternalStringTag | kSymbolTag |
+ kShortExternalStringTag,
EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kExternalStringTag,
EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE =
kTwoByteStringTag | kSymbolTag | kExternalStringTag | kAsciiDataHintTag,
EXTERNAL_ASCII_SYMBOL_TYPE =
- kAsciiStringTag | kSymbolTag | kExternalStringTag,
+ kOneByteStringTag | kAsciiDataHintTag | kSymbolTag | kExternalStringTag,
STRING_TYPE = kTwoByteStringTag | kSeqStringTag,
- ASCII_STRING_TYPE = kAsciiStringTag | kSeqStringTag,
+ ASCII_STRING_TYPE = kOneByteStringTag | kAsciiDataHintTag | kSeqStringTag,
CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag,
- CONS_ASCII_STRING_TYPE = kAsciiStringTag | kConsStringTag,
+ CONS_ASCII_STRING_TYPE =
+ kOneByteStringTag | kAsciiDataHintTag | kConsStringTag,
SLICED_STRING_TYPE = kTwoByteStringTag | kSlicedStringTag,
- SLICED_ASCII_STRING_TYPE = kAsciiStringTag | kSlicedStringTag,
+ SLICED_ASCII_STRING_TYPE =
+ kOneByteStringTag | kAsciiDataHintTag | kSlicedStringTag,
SHORT_EXTERNAL_STRING_TYPE =
kTwoByteStringTag | kExternalStringTag | kShortExternalStringTag,
SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE =
kTwoByteStringTag | kExternalStringTag |
kAsciiDataHintTag | kShortExternalStringTag,
SHORT_EXTERNAL_ASCII_STRING_TYPE =
- kAsciiStringTag | kExternalStringTag | kShortExternalStringTag,
+ kOneByteStringTag | kAsciiDataHintTag |
+ kExternalStringTag | kShortExternalStringTag,
EXTERNAL_STRING_TYPE = kTwoByteStringTag | kExternalStringTag,
EXTERNAL_STRING_WITH_ASCII_DATA_TYPE =
kTwoByteStringTag | kExternalStringTag | kAsciiDataHintTag,
// LAST_STRING_TYPE
- EXTERNAL_ASCII_STRING_TYPE = kAsciiStringTag | kExternalStringTag,
+ EXTERNAL_ASCII_STRING_TYPE =
+ kOneByteStringTag | kAsciiDataHintTag | kExternalStringTag,
PRIVATE_EXTERNAL_ASCII_STRING_TYPE = EXTERNAL_ASCII_STRING_TYPE,
// Objects allocated in their own spaces (never in new space).
@@ -714,6 +750,11 @@ struct ValueInfo : public Malloced {
// A template-ized version of the IsXXX functions.
template <class C> static inline bool Is(Object* obj);
+#ifdef VERIFY_HEAP
+#define DECLARE_VERIFIER(Name) void Name##Verify();
+#else
+#define DECLARE_VERIFIER(Name)
+#endif
class MaybeObject BASE_EMBEDDED {
public:
@@ -732,7 +773,9 @@ class MaybeObject BASE_EMBEDDED {
return reinterpret_cast<Failure*>(this);
}
inline Object* ToObjectUnchecked() {
- ASSERT(!IsFailure());
+ // TODO(jkummerow): Turn this back into an ASSERT when we can be certain
+ // that it never fires in Release mode in the wild.
+ CHECK(!IsFailure());
return reinterpret_cast<Object*>(this);
}
inline Object* ToObjectChecked() {
@@ -747,6 +790,13 @@ class MaybeObject BASE_EMBEDDED {
return true;
}
+ template<typename T>
+ inline bool ToHandle(Handle<T>* obj, Isolate* isolate) {
+ if (IsFailure()) return false;
+ *obj = handle(T::cast(reinterpret_cast<Object*>(this)), isolate);
+ return true;
+ }
+
#ifdef OBJECT_PRINT
// Prints this object with details.
inline void Print() {
@@ -758,7 +808,7 @@ class MaybeObject BASE_EMBEDDED {
void Print(FILE* out);
void PrintLn(FILE* out);
#endif
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
// Verifies the object.
void Verify();
#endif
@@ -781,7 +831,7 @@ class MaybeObject BASE_EMBEDDED {
V(ExternalTwoByteString) \
V(ExternalAsciiString) \
V(SeqTwoByteString) \
- V(SeqAsciiString) \
+ V(SeqOneByteString) \
\
V(ExternalArray) \
V(ExternalByteArray) \
@@ -844,6 +894,7 @@ class MaybeObject BASE_EMBEDDED {
V(UndetectableObject) \
V(AccessCheckNeeded) \
V(JSGlobalPropertyCell) \
+ V(ObjectHashTable) \
class JSReceiver;
@@ -865,6 +916,7 @@ class Object : public MaybeObject {
#undef IS_TYPE_FUNCTION_DECL
inline bool IsFixedArrayBase();
+ inline bool IsExternal();
// Returns true if this object is an instance of the specified
// function template.
@@ -923,6 +975,7 @@ class Object : public MaybeObject {
String* key,
PropertyAttributes* attributes);
+ static Handle<Object> GetProperty(Handle<Object> object, Handle<String> key);
static Handle<Object> GetProperty(Handle<Object> object,
Handle<Object> receiver,
LookupResult* result,
@@ -965,7 +1018,7 @@ class Object : public MaybeObject {
// < the length of the string. Used to implement [] on strings.
inline bool IsStringObjectWithCharacterAt(uint32_t index);
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
// Verify a pointer is a valid object pointer.
static void VerifyPointer(Object* p);
#endif
@@ -1020,9 +1073,8 @@ class Smi: public Object {
}
void SmiPrint(FILE* out);
void SmiPrint(StringStream* accumulator);
-#ifdef DEBUG
- void SmiVerify();
-#endif
+
+ DECLARE_VERIFIER(Smi)
static const int kMinValue =
(static_cast<unsigned int>(-1)) << (kSmiValueSize - 1);
@@ -1093,9 +1145,8 @@ class Failure: public MaybeObject {
}
void FailurePrint(FILE* out);
void FailurePrint(StringStream* accumulator);
-#ifdef DEBUG
- void FailureVerify();
-#endif
+
+ DECLARE_VERIFIER(Failure)
private:
inline intptr_t value() const;
@@ -1226,9 +1277,8 @@ class HeapObject: public Object {
void HeapObjectPrint(FILE* out);
void PrintHeader(FILE* out, const char* id);
#endif
-
-#ifdef DEBUG
- void HeapObjectVerify();
+ DECLARE_VERIFIER(HeapObject)
+#ifdef VERIFY_HEAP
inline void VerifyObjectField(int offset);
inline void VerifySmiField(int offset);
@@ -1314,9 +1364,7 @@ class HeapNumber: public HeapObject {
}
void HeapNumberPrint(FILE* out);
void HeapNumberPrint(StringStream* accumulator);
-#ifdef DEBUG
- void HeapNumberVerify();
-#endif
+ DECLARE_VERIFIER(HeapNumber)
inline int get_exponent();
inline int get_sign();
@@ -1445,10 +1493,14 @@ class JSReceiver: public HeapObject {
String* name);
PropertyAttributes GetLocalPropertyAttribute(String* name);
+ inline PropertyAttributes GetElementAttribute(uint32_t index);
+ inline PropertyAttributes GetLocalElementAttribute(uint32_t index);
+
// Can cause a GC.
inline bool HasProperty(String* name);
inline bool HasLocalProperty(String* name);
inline bool HasElement(uint32_t index);
+ inline bool HasLocalElement(uint32_t index);
// Return the object's prototype (might be Heap::null_value()).
inline Object* GetPrototype();
@@ -1466,17 +1518,18 @@ class JSReceiver: public HeapObject {
// Lookup a property. If found, the result is valid and has
// detailed information.
- void LocalLookup(String* name, LookupResult* result);
+ void LocalLookup(String* name, LookupResult* result,
+ bool search_hidden_prototypes = false);
void Lookup(String* name, LookupResult* result);
protected:
Smi* GenerateIdentityHash();
private:
- PropertyAttributes GetPropertyAttribute(JSReceiver* receiver,
- LookupResult* result,
- String* name,
- bool continue_search);
+ PropertyAttributes GetPropertyAttributeForResult(JSReceiver* receiver,
+ LookupResult* result,
+ String* name,
+ bool continue_search);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
};
@@ -1525,6 +1578,8 @@ class JSObject: public JSReceiver {
// Returns true if an object has elements of FAST_ELEMENTS or
// FAST_SMI_ONLY_ELEMENTS.
inline bool HasFastSmiOrObjectElements();
+ // Returns true if an object has any of the fast elements kinds.
+ inline bool HasFastElements();
// Returns true if an object has elements of FAST_DOUBLE_ELEMENTS
// ElementsKind.
inline bool HasFastDoubleElements();
@@ -1604,6 +1659,18 @@ class JSObject: public JSReceiver {
Handle<Object> value,
PropertyAttributes attributes);
+ // Try to follow an existing transition to a field with attributes NONE. The
+ // return value indicates whether the transition was successful.
+ static inline bool TryTransitionToField(Handle<JSObject> object,
+ Handle<String> key);
+
+ inline int LastAddedFieldIndex();
+
+ // Extend the receiver with a single fast property appeared first in the
+ // passed map. This also extends the property backing store if necessary.
+ static void AddFastPropertyUsingMap(Handle<JSObject> object, Handle<Map> map);
+ inline MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(Map* map);
+
// Can cause GC.
MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
String* key,
@@ -1651,12 +1718,16 @@ class JSObject: public JSReceiver {
LookupResult* result,
String* name,
bool continue_search);
+ PropertyAttributes GetElementAttributeWithReceiver(JSReceiver* receiver,
+ uint32_t index,
+ bool continue_search);
static void DefineAccessor(Handle<JSObject> object,
Handle<String> name,
Handle<Object> getter,
Handle<Object> setter,
PropertyAttributes attributes);
+ // Can cause GC.
MUST_USE_RESULT MaybeObject* DefineAccessor(String* name,
Object* getter,
Object* setter,
@@ -1732,6 +1803,7 @@ class JSObject: public JSReceiver {
static Handle<Object> DeleteProperty(Handle<JSObject> obj,
Handle<String> name);
+ // Can cause GC.
MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode);
static Handle<Object> DeleteElement(Handle<JSObject> obj, uint32_t index);
@@ -1770,36 +1842,18 @@ class JSObject: public JSReceiver {
// be represented as a double and not a Smi.
bool ShouldConvertToFastDoubleElements(bool* has_smi_only_elements);
- // Tells whether the index'th element is present.
- bool HasElementWithReceiver(JSReceiver* receiver, uint32_t index);
-
// Computes the new capacity when expanding the elements of a JSObject.
static int NewElementsCapacity(int old_capacity) {
// (old_capacity + 50%) + 16
return old_capacity + (old_capacity >> 1) + 16;
}
- // Tells whether the index'th element is present and how it is stored.
- enum LocalElementType {
- // There is no element with given index.
- UNDEFINED_ELEMENT,
-
- // Element with given index is handled by interceptor.
- INTERCEPTED_ELEMENT,
+ PropertyType GetLocalPropertyType(String* name);
+ PropertyType GetLocalElementType(uint32_t index);
- // Element with given index is character in string.
- STRING_CHARACTER_ELEMENT,
-
- // Element with given index is stored in fast backing store.
- FAST_ELEMENT,
-
- // Element with given index is stored in slow backing store.
- DICTIONARY_ELEMENT
- };
-
- LocalElementType HasLocalElement(uint32_t index);
-
- bool HasElementWithInterceptor(JSReceiver* receiver, uint32_t index);
+ // These methods do not perform access checks!
+ AccessorPair* GetLocalPropertyAccessorPair(String* name);
+ AccessorPair* GetLocalElementAccessorPair(uint32_t index);
MUST_USE_RESULT MaybeObject* SetFastElement(uint32_t index,
Object* value,
@@ -1826,7 +1880,7 @@ class JSObject: public JSReceiver {
StrictModeFlag strict_mode);
// Empty handle is returned if the element cannot be set to the given value.
- static MUST_USE_RESULT Handle<Object> SetElement(
+ static Handle<Object> SetElement(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
@@ -1979,7 +2033,7 @@ class JSObject: public JSReceiver {
Object* value,
PropertyAttributes attributes);
- // Add a property to an object.
+ // Add a property to an object. May cause GC.
MUST_USE_RESULT MaybeObject* AddProperty(
String* name,
Object* value,
@@ -2061,9 +2115,7 @@ class JSObject: public JSReceiver {
}
void JSObjectPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSObjectVerify();
-#endif
+ DECLARE_VERIFIER(JSObject)
#ifdef OBJECT_PRINT
inline void PrintProperties() {
PrintProperties(stdout);
@@ -2152,6 +2204,15 @@ class JSObject: public JSReceiver {
static inline int SizeOf(Map* map, HeapObject* object);
};
+ // Enqueue change record for Object.observe. May cause GC.
+ static void EnqueueChangeRecord(Handle<JSObject> object,
+ const char* type,
+ Handle<String> name,
+ Handle<Object> old_value);
+
+ // Deliver change records to observers. May cause GC.
+ static void DeliverChangeRecords(Isolate* isolate);
+
private:
friend class DictionaryElementsAccessor;
@@ -2159,6 +2220,14 @@ class JSObject: public JSReceiver {
Object* structure,
uint32_t index,
Object* holder);
+ MUST_USE_RESULT PropertyAttributes GetElementAttributeWithInterceptor(
+ JSReceiver* receiver,
+ uint32_t index,
+ bool continue_search);
+ MUST_USE_RESULT PropertyAttributes GetElementAttributeWithoutInterceptor(
+ JSReceiver* receiver,
+ uint32_t index,
+ bool continue_search);
MUST_USE_RESULT MaybeObject* SetElementWithCallback(
Object* structure,
uint32_t index,
@@ -2303,12 +2372,12 @@ class FixedArray: public FixedArrayBase {
inline void set_unchecked(Heap* heap, int index, Object* value,
WriteBarrierMode mode);
- // Gives access to raw memory which stores the array's data.
- inline Object** data_start();
-
inline Object** GetFirstElementAddress();
inline bool ContainsOnlySmisOrHoles();
+ // Gives access to raw memory which stores the array's data.
+ inline Object** data_start();
+
// Copy operations.
MUST_USE_RESULT inline MaybeObject* Copy();
MUST_USE_RESULT MaybeObject* CopySize(int new_length);
@@ -2345,8 +2414,8 @@ class FixedArray: public FixedArrayBase {
}
void FixedArrayPrint(FILE* out);
#endif
+ DECLARE_VERIFIER(FixedArray)
#ifdef DEBUG
- void FixedArrayVerify();
// Checks if two FixedArrays have identical contents.
bool IsEqualTo(FixedArray* other);
#endif
@@ -2368,23 +2437,6 @@ class FixedArray: public FixedArrayBase {
}
};
- // WhitenessWitness is used to prove that a descriptor array is white
- // (unmarked), so incremental write barriers can be skipped because the
- // marking invariant cannot be broken and slots pointing into evacuation
- // candidates will be discovered when the object is scanned. A witness is
- // always stack-allocated right after creating an array. By allocating a
- // witness, incremental marking is globally disabled. The witness is then
- // passed along wherever needed to statically prove that the array is known to
- // be white.
- class WhitenessWitness {
- public:
- inline explicit WhitenessWitness(FixedArray* array);
- inline ~WhitenessWitness();
-
- private:
- IncrementalMarking* marking_;
- };
-
protected:
// Set operation on FixedArray without using write barriers. Can
// only be used for storing old space objects or smis.
@@ -2400,6 +2452,8 @@ class FixedArray: public FixedArrayBase {
Object* value);
private:
+ STATIC_CHECK(kHeaderSize == Internals::kFixedArrayHeaderSize);
+
DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
};
@@ -2425,6 +2479,9 @@ class FixedDoubleArray: public FixedArrayBase {
return kHeaderSize + length * kDoubleSize;
}
+ // Gives access to raw memory which stores the array's data.
+ inline double* data_start();
+
// Code Generation support.
static int OffsetOfElementAt(int index) { return SizeFor(index); }
@@ -2449,10 +2506,7 @@ class FixedDoubleArray: public FixedArrayBase {
}
void FixedDoubleArrayPrint(FILE* out);
#endif
-
-#ifdef DEBUG
- void FixedDoubleArrayVerify();
-#endif
+ DECLARE_VERIFIER(FixedDoubleArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
@@ -2461,13 +2515,31 @@ class FixedDoubleArray: public FixedArrayBase {
// DescriptorArrays are fixed arrays used to hold instance descriptors.
// The format of the these objects is:
-// [0]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
+// [0]: Number of descriptors
+// [1]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
// [0]: pointer to fixed array with enum cache
// [1]: either Smi(0) or pointer to fixed array with indices
-// [1]: first key
-// [length() - kDescriptorSize]: last key
+// [2]: first key
+// [2 + number of descriptors * kDescriptorSize]: start of slack
class DescriptorArray: public FixedArray {
public:
+ // WhitenessWitness is used to prove that a descriptor array is white
+ // (unmarked), so incremental write barriers can be skipped because the
+ // marking invariant cannot be broken and slots pointing into evacuation
+ // candidates will be discovered when the object is scanned. A witness is
+ // always stack-allocated right after creating an array. By allocating a
+ // witness, incremental marking is globally disabled. The witness is then
+ // passed along wherever needed to statically prove that the array is known to
+ // be white.
+ class WhitenessWitness {
+ public:
+ inline explicit WhitenessWitness(FixedArray* array);
+ inline ~WhitenessWitness();
+
+ private:
+ IncrementalMarking* marking_;
+ };
+
// Returns true for both shared empty_descriptor_array and for smis, which the
// map uses to encode additional bit fields when the descriptor array is not
// yet used.
@@ -2477,20 +2549,47 @@ class DescriptorArray: public FixedArray {
int number_of_descriptors() {
ASSERT(length() >= kFirstIndex || IsEmpty());
int len = length();
- return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize;
+ return len == 0 ? 0 : Smi::cast(get(kDescriptorLengthIndex))->value();
+ }
+
+ int number_of_descriptors_storage() {
+ int len = length();
+ return len == 0 ? 0 : (len - kFirstIndex) / kDescriptorSize;
+ }
+
+ int NumberOfSlackDescriptors() {
+ return number_of_descriptors_storage() - number_of_descriptors();
}
+ inline void SetNumberOfDescriptors(int number_of_descriptors);
inline int number_of_entries() { return number_of_descriptors(); }
- inline int NextEnumerationIndex() { return number_of_descriptors() + 1; }
bool HasEnumCache() {
return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi();
}
- Object* GetEnumCache() {
+ void CopyEnumCacheFrom(DescriptorArray* array) {
+ set(kEnumCacheIndex, array->get(kEnumCacheIndex));
+ }
+
+ FixedArray* GetEnumCache() {
ASSERT(HasEnumCache());
FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
- return bridge->get(kEnumCacheBridgeCacheIndex);
+ return FixedArray::cast(bridge->get(kEnumCacheBridgeCacheIndex));
+ }
+
+ bool HasEnumIndicesCache() {
+ if (IsEmpty()) return false;
+ Object* object = get(kEnumCacheIndex);
+ if (object->IsSmi()) return false;
+ FixedArray* bridge = FixedArray::cast(object);
+ return !bridge->get(kEnumCacheBridgeIndicesCacheIndex)->IsSmi();
+ }
+
+ FixedArray* GetEnumIndicesCache() {
+ ASSERT(HasEnumIndicesCache());
+ FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
+ return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex));
}
Object** GetEnumCacheSlot() {
@@ -2499,6 +2598,8 @@ class DescriptorArray: public FixedArray {
kEnumCacheOffset);
}
+ void ClearEnumCache();
+
// Initialize or change the enum cache,
// using the supplied storage for the small "bridge".
void SetEnumCache(FixedArray* bridge_storage,
@@ -2526,13 +2627,13 @@ class DescriptorArray: public FixedArray {
inline void Set(int descriptor_number,
Descriptor* desc,
const WhitenessWitness&);
+ inline void Set(int descriptor_number, Descriptor* desc);
// Append automatically sets the enumeration index. This should only be used
// to add descriptors in bulk at the end, followed by sorting the descriptor
// array.
- inline void Append(Descriptor* desc,
- const WhitenessWitness&,
- int number_of_set_descriptors);
+ inline void Append(Descriptor* desc, const WhitenessWitness&);
+ inline void Append(Descriptor* desc);
// Transfer a complete descriptor from the src descriptor array to this
// descriptor array.
@@ -2541,23 +2642,22 @@ class DescriptorArray: public FixedArray {
int src_index,
const WhitenessWitness&);
+ MUST_USE_RESULT MaybeObject* CopyUpTo(int enumeration_index);
+
// Sort the instance descriptors by the hash codes of their keys.
void Sort();
- inline void SwapSortedKeys(int first, int second);
// Search the instance descriptors for given name.
- INLINE(int Search(String* name));
+ INLINE(int Search(String* name, int number_of_own_descriptors));
// As the above, but uses DescriptorLookupCache and updates it when
// necessary.
- INLINE(int SearchWithCache(String* name));
-
- // Tells whether the name is present int the array.
- bool Contains(String* name) { return kNotFound != Search(name); }
+ INLINE(int SearchWithCache(String* name, Map* map));
// Allocates a DescriptorArray, but returns the singleton
// empty descriptor array object if number_of_descriptors is 0.
- MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors);
+ MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors,
+ int slack = 0);
// Casting.
static inline DescriptorArray* cast(Object* obj);
@@ -2565,8 +2665,9 @@ class DescriptorArray: public FixedArray {
// Constant for denoting key was not found.
static const int kNotFound = -1;
- static const int kEnumCacheIndex = 0;
- static const int kFirstIndex = 1;
+ static const int kDescriptorLengthIndex = 0;
+ static const int kEnumCacheIndex = 1;
+ static const int kFirstIndex = 2;
// The length of the "bridge" to the enum cache.
static const int kEnumCacheBridgeLength = 2;
@@ -2574,7 +2675,8 @@ class DescriptorArray: public FixedArray {
static const int kEnumCacheBridgeIndicesCacheIndex = 1;
// Layout description.
- static const int kEnumCacheOffset = FixedArray::kHeaderSize;
+ static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
+ static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
// Layout description for the bridge array.
@@ -2596,7 +2698,7 @@ class DescriptorArray: public FixedArray {
#ifdef DEBUG
// Is the descriptor array sorted and without duplicates?
- bool IsSortedNoDuplicates();
+ bool IsSortedNoDuplicates(int valid_descriptors = -1);
// Is the descriptor array consistent with the back pointers in targets?
bool IsConsistentWithBackPointers(Map* current_map);
@@ -2649,24 +2751,21 @@ class DescriptorArray: public FixedArray {
kDescriptorValue;
}
- // Swap operation on FixedArray without using write barriers.
- static inline void NoIncrementalWriteBarrierSwap(
- FixedArray* array, int first, int second);
-
// Swap first and second descriptor.
- inline void NoIncrementalWriteBarrierSwapDescriptors(
- int first, int second);
+ inline void SwapSortedKeys(int first, int second);
DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
};
-template<typename T>
-inline int LinearSearch(T* array, String* name, int len);
+enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
+template<SearchMode search_mode, typename T>
+inline int LinearSearch(T* array, String* name, int len, int valid_entries);
-template<typename T>
-inline int Search(T* array, String* name);
+
+template<SearchMode search_mode, typename T>
+inline int Search(T* array, String* name, int valid_entries = 0);
// HashTable is a subclass of FixedArray that implements a hash table
@@ -2868,11 +2967,12 @@ class HashTable: public FixedArray {
return (hash + GetProbeOffset(number)) & (size - 1);
}
- static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
+ inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) {
return hash & (size - 1);
}
- static uint32_t NextProbe(uint32_t last, uint32_t number, uint32_t size) {
+ inline static uint32_t NextProbe(
+ uint32_t last, uint32_t number, uint32_t size) {
return (last + number) & (size - 1);
}
@@ -2923,7 +3023,7 @@ class SymbolTableShape : public BaseShape<HashTableKey*> {
static const int kEntrySize = 1;
};
-class SeqAsciiString;
+class SeqOneByteString;
// SymbolTable.
//
@@ -2939,7 +3039,7 @@ class SymbolTable: public HashTable<SymbolTableShape, HashTableKey*> {
MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(Vector<const char> str,
Object** s);
MUST_USE_RESULT MaybeObject* LookupSubStringAsciiSymbol(
- Handle<SeqAsciiString> str,
+ Handle<SeqOneByteString> str,
int from,
int length,
Object** s);
@@ -2959,6 +3059,8 @@ class SymbolTable: public HashTable<SymbolTableShape, HashTableKey*> {
private:
MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s);
+ template <bool seq_ascii> friend class JsonParser;
+
DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable);
};
@@ -3340,9 +3442,7 @@ class JSFunctionResultCache: public FixedArray {
// Casting
static inline JSFunctionResultCache* cast(Object* obj);
-#ifdef DEBUG
- void JSFunctionResultCacheVerify();
-#endif
+ DECLARE_VERIFIER(JSFunctionResultCache)
};
@@ -3562,9 +3662,7 @@ class NormalizedMapCache: public FixedArray {
// Casting
static inline NormalizedMapCache* cast(Object* obj);
-#ifdef DEBUG
- void NormalizedMapCacheVerify();
-#endif
+ DECLARE_VERIFIER(NormalizedMapCache)
};
@@ -3613,9 +3711,7 @@ class ByteArray: public FixedArrayBase {
}
void ByteArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ByteArrayVerify();
-#endif
+ DECLARE_VERIFIER(ByteArray)
// Layout description.
static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
@@ -3649,9 +3745,7 @@ class FreeSpace: public HeapObject {
}
void FreeSpacePrint(FILE* out);
#endif
-#ifdef DEBUG
- void FreeSpaceVerify();
-#endif
+ DECLARE_VERIFIER(FreeSpace)
// Layout description.
// Size is smi tagged when it is stored.
@@ -3731,9 +3825,7 @@ class ExternalPixelArray: public ExternalArray {
}
void ExternalPixelArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalPixelArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalPixelArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalPixelArray);
@@ -3760,9 +3852,7 @@ class ExternalByteArray: public ExternalArray {
}
void ExternalByteArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalByteArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalByteArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalByteArray);
@@ -3789,9 +3879,7 @@ class ExternalUnsignedByteArray: public ExternalArray {
}
void ExternalUnsignedByteArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalUnsignedByteArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalUnsignedByteArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedByteArray);
@@ -3818,9 +3906,7 @@ class ExternalShortArray: public ExternalArray {
}
void ExternalShortArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalShortArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalShortArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalShortArray);
@@ -3847,9 +3933,7 @@ class ExternalUnsignedShortArray: public ExternalArray {
}
void ExternalUnsignedShortArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalUnsignedShortArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalUnsignedShortArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedShortArray);
@@ -3876,9 +3960,7 @@ class ExternalIntArray: public ExternalArray {
}
void ExternalIntArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalIntArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalIntArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalIntArray);
@@ -3905,9 +3987,7 @@ class ExternalUnsignedIntArray: public ExternalArray {
}
void ExternalUnsignedIntArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalUnsignedIntArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalUnsignedIntArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedIntArray);
@@ -3934,9 +4014,7 @@ class ExternalFloatArray: public ExternalArray {
}
void ExternalFloatArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ExternalFloatArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalFloatArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloatArray);
@@ -3963,9 +4041,7 @@ class ExternalDoubleArray: public ExternalArray {
}
void ExternalDoubleArrayPrint(FILE* out);
#endif // OBJECT_PRINT
-#ifdef DEBUG
- void ExternalDoubleArrayVerify();
-#endif // DEBUG
+ DECLARE_VERIFIER(ExternalDoubleArray)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalDoubleArray);
@@ -4233,8 +4309,12 @@ class Code: public HeapObject {
DECL_ACCESSORS(deoptimization_data, FixedArray)
// [type_feedback_info]: Struct containing type feedback information.
- // Will contain either a TypeFeedbackInfo object, or undefined.
+ // STUBs can use this slot to store arbitrary information as a Smi.
+ // Will contain either a TypeFeedbackInfo object, or undefined, or a Smi.
DECL_ACCESSORS(type_feedback_info, Object)
+ inline void InitializeTypeFeedbackInfoNoWriteBarrier(Object* value);
+ inline int stub_info();
+ inline void set_stub_info(int info);
// [gc_metadata]: Field used to hold GC related metadata. The contents of this
// field does not have to be traced during garbage collection since
@@ -4246,6 +4326,11 @@ class Code: public HeapObject {
inline void set_ic_age(int count);
inline int ic_age();
+ // [prologue_offset]: Offset of the function prologue, used for aging
+ // FUNCTIONs and OPTIMIZED_FUNCTIONs.
+ inline int prologue_offset();
+ inline void set_prologue_offset(int offset);
+
// Unchecked accessors to be used during GC.
inline ByteArray* unchecked_relocation_info();
inline FixedArray* unchecked_deoptimization_data();
@@ -4340,21 +4425,6 @@ class Code: public HeapObject {
inline byte unary_op_type();
inline void set_unary_op_type(byte value);
- // [type-recording binary op type]: For kind BINARY_OP_IC.
- inline byte binary_op_type();
- inline void set_binary_op_type(byte value);
- inline byte binary_op_result_type();
- inline void set_binary_op_result_type(byte value);
-
- // [compare state]: For kind COMPARE_IC, tells what state the stub is in.
- inline byte compare_state();
- inline void set_compare_state(byte value);
-
- // [compare_operation]: For kind COMPARE_IC tells what compare operation the
- // stub was generated for.
- inline byte compare_operation();
- inline void set_compare_operation(byte value);
-
// [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in.
inline byte to_boolean_state();
inline void set_to_boolean_state(byte value);
@@ -4488,12 +4558,27 @@ class Code: public HeapObject {
}
void CodePrint(FILE* out);
#endif
-#ifdef DEBUG
- void CodeVerify();
-#endif
+ DECLARE_VERIFIER(Code)
+
void ClearInlineCaches();
void ClearTypeFeedbackCells(Heap* heap);
+#define DECLARE_CODE_AGE_ENUM(X) k##X##CodeAge,
+ enum Age {
+ kNoAge = 0,
+ CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM)
+ kAfterLastCodeAge,
+ kLastCodeAge = kAfterLastCodeAge - 1,
+ kCodeAgeCount = kAfterLastCodeAge - 1
+ };
+#undef DECLARE_CODE_AGE_ENUM
+
+ // Code aging
+ static void MakeCodeAgeSequenceYoung(byte* sequence);
+ void MakeOlder(MarkingParity);
+ static bool IsYoungSequence(byte* sequence);
+ bool IsOld();
+
// Max loop nesting marker used to postpose OSR. We don't take loop
// nesting that is deeper than 5 levels into account.
static const int kMaxLoopNestingMarker = 6;
@@ -4513,8 +4598,10 @@ class Code: public HeapObject {
static const int kKindSpecificFlags1Offset = kFlagsOffset + kIntSize;
static const int kKindSpecificFlags2Offset =
kKindSpecificFlags1Offset + kIntSize;
+ // Note: We might be able to squeeze this into the flags above.
+ static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
- static const int kHeaderPaddingStart = kKindSpecificFlags2Offset + kIntSize;
+ static const int kHeaderPaddingStart = kPrologueOffset + kIntSize;
// Add padding to align the instruction start following right after
// the Code object header.
@@ -4548,18 +4635,6 @@ class Code: public HeapObject {
static const int kUnaryOpTypeFirstBit =
kStackSlotsFirstBit + kStackSlotsBitCount;
static const int kUnaryOpTypeBitCount = 3;
- static const int kBinaryOpTypeFirstBit =
- kStackSlotsFirstBit + kStackSlotsBitCount;
- static const int kBinaryOpTypeBitCount = 3;
- static const int kBinaryOpResultTypeFirstBit =
- kBinaryOpTypeFirstBit + kBinaryOpTypeBitCount;
- static const int kBinaryOpResultTypeBitCount = 3;
- static const int kCompareStateFirstBit =
- kStackSlotsFirstBit + kStackSlotsBitCount;
- static const int kCompareStateBitCount = 3;
- static const int kCompareOperationFirstBit =
- kCompareStateFirstBit + kCompareStateBitCount;
- static const int kCompareOperationBitCount = 4;
static const int kToBooleanStateFirstBit =
kStackSlotsFirstBit + kStackSlotsBitCount;
static const int kToBooleanStateBitCount = 8;
@@ -4569,11 +4644,6 @@ class Code: public HeapObject {
STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
STATIC_ASSERT(kUnaryOpTypeFirstBit + kUnaryOpTypeBitCount <= 32);
- STATIC_ASSERT(kBinaryOpTypeFirstBit + kBinaryOpTypeBitCount <= 32);
- STATIC_ASSERT(kBinaryOpResultTypeFirstBit +
- kBinaryOpResultTypeBitCount <= 32);
- STATIC_ASSERT(kCompareStateFirstBit + kCompareStateBitCount <= 32);
- STATIC_ASSERT(kCompareOperationFirstBit + kCompareOperationBitCount <= 32);
STATIC_ASSERT(kToBooleanStateFirstBit + kToBooleanStateBitCount <= 32);
STATIC_ASSERT(kHasFunctionCacheFirstBit + kHasFunctionCacheBitCount <= 32);
@@ -4581,14 +4651,6 @@ class Code: public HeapObject {
kStackSlotsFirstBit, kStackSlotsBitCount> {}; // NOLINT
class UnaryOpTypeField: public BitField<int,
kUnaryOpTypeFirstBit, kUnaryOpTypeBitCount> {}; // NOLINT
- class BinaryOpTypeField: public BitField<int,
- kBinaryOpTypeFirstBit, kBinaryOpTypeBitCount> {}; // NOLINT
- class BinaryOpResultTypeField: public BitField<int,
- kBinaryOpResultTypeFirstBit, kBinaryOpResultTypeBitCount> {}; // NOLINT
- class CompareStateField: public BitField<int,
- kCompareStateFirstBit, kCompareStateBitCount> {}; // NOLINT
- class CompareOperationField: public BitField<int,
- kCompareOperationFirstBit, kCompareOperationBitCount> {}; // NOLINT
class ToBooleanStateField: public BitField<int,
kToBooleanStateFirstBit, kToBooleanStateBitCount> {}; // NOLINT
class HasFunctionCacheField: public BitField<bool,
@@ -4622,6 +4684,20 @@ class Code: public HeapObject {
TypeField::kMask | CacheHolderField::kMask;
private:
+ friend class RelocIterator;
+
+ // Code aging
+ byte* FindCodeAgeSequence();
+ static void GetCodeAgeAndParity(Code* code, Age* age,
+ MarkingParity* parity);
+ static void GetCodeAgeAndParity(byte* sequence, Age* age,
+ MarkingParity* parity);
+ static Code* GetCodeAgeStub(Age age, MarkingParity parity);
+
+ // Code aging -- platform-specific
+ static void PatchPlatformCodeAge(byte* sequence, Age age,
+ MarkingParity parity);
+
DISALLOW_IMPLICIT_CONSTRUCTORS(Code);
};
@@ -4672,6 +4748,8 @@ class Map: public HeapObject {
class IsShared: public BitField<bool, 22, 1> {};
class FunctionWithPrototype: public BitField<bool, 23, 1> {};
class DictionaryMap: public BitField<bool, 24, 1> {};
+ class OwnsDescriptors: public BitField<bool, 25, 1> {};
+ class IsObserved: public BitField<bool, 26, 1> {};
// Tells whether the object in the prototype property will be used
// for instances created from this function. If the prototype
@@ -4797,8 +4875,11 @@ class Map: public HeapObject {
inline Map* elements_transition_map();
MUST_USE_RESULT inline MaybeObject* set_elements_transition_map(
Map* transitioned_map);
- inline void SetTransition(int index, Map* target);
- MUST_USE_RESULT inline MaybeObject* AddTransition(String* key, Map* target);
+ inline void SetTransition(int transition_index, Map* target);
+ inline Map* GetTransition(int transition_index);
+ MUST_USE_RESULT inline MaybeObject* AddTransition(String* key,
+ Map* target,
+ SimpleTransitionFlag flag);
DECL_ACCESSORS(transitions, TransitionArray)
inline void ClearTransitions(Heap* heap,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
@@ -4836,14 +4917,8 @@ class Map: public HeapObject {
inline JSFunction* unchecked_constructor();
// [instance descriptors]: describes the object.
- inline DescriptorArray* instance_descriptors();
- MUST_USE_RESULT inline MaybeObject* SetDescriptors(
- DescriptorArray* descriptors,
- WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- static void SetDescriptors(Handle<Map> map,
- Handle<DescriptorArray> descriptors);
- MUST_USE_RESULT inline MaybeObject* InitializeDescriptors(
- DescriptorArray* descriptors);
+ DECL_ACCESSORS(instance_descriptors, DescriptorArray)
+ inline void InitializeDescriptors(DescriptorArray* descriptors);
// [stub cache]: contains stubs compiled for this map.
DECL_ACCESSORS(code_cache, Object)
@@ -4920,31 +4995,50 @@ class Map: public HeapObject {
}
void SetNumberOfOwnDescriptors(int number) {
+ ASSERT(number <= instance_descriptors()->number_of_descriptors());
set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number));
}
+ inline JSGlobalPropertyCell* RetrieveDescriptorsPointer();
+
int EnumLength() {
return EnumLengthBits::decode(bit_field3());
}
- void SetEnumLength(int index) {
- set_bit_field3(EnumLengthBits::update(bit_field3(), index));
+ void SetEnumLength(int length) {
+ if (length != kInvalidEnumCache) {
+ ASSERT(length >= 0);
+ ASSERT(length == 0 || instance_descriptors()->HasEnumCache());
+ ASSERT(length <= NumberOfOwnDescriptors());
+ }
+ set_bit_field3(EnumLengthBits::update(bit_field3(), length));
}
+
+ inline bool owns_descriptors();
+ inline void set_owns_descriptors(bool is_shared);
+ inline bool is_observed();
+ inline void set_is_observed(bool is_observed);
+
MUST_USE_RESULT MaybeObject* RawCopy(int instance_size);
MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors();
MUST_USE_RESULT MaybeObject* CopyDropDescriptors();
MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors(
DescriptorArray* descriptors,
String* name,
- TransitionFlag flag);
+ TransitionFlag flag,
+ int descriptor_index);
+ MUST_USE_RESULT MaybeObject* ShareDescriptor(DescriptorArray* descriptors,
+ Descriptor* descriptor);
MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor,
TransitionFlag flag);
MUST_USE_RESULT MaybeObject* CopyInsertDescriptor(Descriptor* descriptor,
TransitionFlag flag);
- MUST_USE_RESULT MaybeObject* CopyReplaceDescriptor(Descriptor* descriptor,
- int index,
- TransitionFlag flag);
+ MUST_USE_RESULT MaybeObject* CopyReplaceDescriptor(
+ DescriptorArray* descriptors,
+ Descriptor* descriptor,
+ int index,
+ TransitionFlag flag);
MUST_USE_RESULT MaybeObject* CopyAsElementsKind(ElementsKind kind,
TransitionFlag flag);
@@ -4966,7 +5060,8 @@ class Map: public HeapObject {
// Returns the number of properties described in instance_descriptors
// filtering out properties with the specified attributes.
- int NumberOfDescribedProperties(PropertyAttributes filter = NONE);
+ int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS,
+ PropertyAttributes filter = NONE);
// Casting.
static inline Map* cast(Object* obj);
@@ -4987,8 +5082,10 @@ class Map: public HeapObject {
// Extend the descriptor array of the map with the list of descriptors.
// In case of duplicates, the latest descriptor is used.
- static void CopyAppendCallbackDescriptors(Handle<Map> map,
- Handle<Object> descriptors);
+ static void AppendCallbackDescriptors(Handle<Map> map,
+ Handle<Object> descriptors);
+
+ static void EnsureDescriptorSlack(Handle<Map> map, int slack);
// Returns the found code or undefined if absent.
Object* FindInCodeCache(String* name, Code::Flags flags);
@@ -5026,14 +5123,14 @@ class Map: public HeapObject {
Handle<Map> FindTransitionedMap(MapHandleList* candidates);
Map* FindTransitionedMap(MapList* candidates);
- // Zaps the contents of backing data structures in debug mode. Note that the
+ // Zaps the contents of backing data structures. Note that the
// heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects
// holding weak references when incremental marking is used, because it also
// iterates over objects that are otherwise unreachable.
-#ifdef DEBUG
+ // In general we only want to call these functions in release mode when
+ // heap verification is turned on.
void ZapPrototypeTransitions();
void ZapTransitions();
-#endif
// Dispatched behavior.
#ifdef OBJECT_PRINT
@@ -5042,8 +5139,9 @@ class Map: public HeapObject {
}
void MapPrint(FILE* out);
#endif
-#ifdef DEBUG
- void MapVerify();
+ DECLARE_VERIFIER(Map)
+
+#ifdef VERIFY_HEAP
void SharedMapVerify();
#endif
@@ -5070,7 +5168,7 @@ class Map: public HeapObject {
static const int kMaxPreAllocatedPropertyFields = 255;
- // Constant for denoting that the Enum Cache field was not yet used.
+ // Constant for denoting that the enum cache is not yet initialized.
static const int kInvalidEnumCache = EnumLengthBits::kMax;
// Layout description.
@@ -5084,11 +5182,12 @@ class Map: public HeapObject {
// indirection.
static const int kTransitionsOrBackPointerOffset =
kConstructorOffset + kPointerSize;
- static const int kCodeCacheOffset =
+ static const int kDescriptorsOffset =
kTransitionsOrBackPointerOffset + kPointerSize;
+ static const int kCodeCacheOffset =
+ kDescriptorsOffset + kPointerSize;
static const int kBitField3Offset = kCodeCacheOffset + kPointerSize;
- static const int kPadStart = kBitField3Offset + kPointerSize;
- static const int kSize = MAP_POINTER_ALIGN(kPadStart);
+ static const int kSize = kBitField3Offset + kPointerSize;
// Layout of pointer fields. Heap iteration code relies on them
// being continuously allocated.
@@ -5246,9 +5345,7 @@ class Script: public Struct {
}
void ScriptPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ScriptVerify();
-#endif
+ DECLARE_VERIFIER(Script)
static const int kSourceOffset = HeapObject::kHeaderSize;
static const int kNameOffset = kSourceOffset + kPointerSize;
@@ -5728,9 +5825,7 @@ class SharedFunctionInfo: public HeapObject {
}
void SharedFunctionInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void SharedFunctionInfoVerify();
-#endif
+ DECLARE_VERIFIER(SharedFunctionInfo)
void ResetForNewContext(int new_ic_age);
@@ -5964,9 +6059,7 @@ class JSModule: public JSObject {
}
void JSModulePrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSModuleVerify();
-#endif
+ DECLARE_VERIFIER(JSModule)
// Layout description.
static const int kContextOffset = JSObject::kHeaderSize;
@@ -6069,8 +6162,6 @@ class JSFunction: public JSObject {
// The initial map for an object created by this constructor.
inline Map* initial_map();
inline void set_initial_map(Map* value);
- MUST_USE_RESULT inline MaybeObject* set_initial_map_and_cache_transitions(
- Map* value);
inline bool has_initial_map();
// Get and set the prototype property on a JSFunction. If the
@@ -6127,9 +6218,7 @@ class JSFunction: public JSObject {
}
void JSFunctionPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSFunctionVerify();
-#endif
+ DECLARE_VERIFIER(JSFunction)
// Returns the number of allocated literals.
inline int NumberOfLiterals();
@@ -6188,9 +6277,7 @@ class JSGlobalProxy : public JSObject {
}
void JSGlobalProxyPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSGlobalProxyVerify();
-#endif
+ DECLARE_VERIFIER(JSGlobalProxy)
// Layout description.
static const int kNativeContextOffset = JSObject::kHeaderSize;
@@ -6237,7 +6324,7 @@ class GlobalObject: public JSObject {
Handle<GlobalObject> global,
Handle<String> name);
// TODO(kmillikin): This function can be eliminated once the stub cache is
- // full handlified (and the static helper can be written directly).
+ // fully handlified (and the static helper can be written directly).
MUST_USE_RESULT MaybeObject* EnsurePropertyCell(String* name);
// Casting.
@@ -6268,9 +6355,7 @@ class JSGlobalObject: public GlobalObject {
}
void JSGlobalObjectPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSGlobalObjectVerify();
-#endif
+ DECLARE_VERIFIER(JSGlobalObject)
// Layout description.
static const int kSize = GlobalObject::kHeaderSize;
@@ -6302,9 +6387,7 @@ class JSBuiltinsObject: public GlobalObject {
}
void JSBuiltinsObjectPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSBuiltinsObjectVerify();
-#endif
+ DECLARE_VERIFIER(JSBuiltinsObject)
// Layout description. The size of the builtins object includes
// room for two pointers per runtime routine written in javascript
@@ -6345,9 +6428,7 @@ class JSValue: public JSObject {
}
void JSValuePrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSValueVerify();
-#endif
+ DECLARE_VERIFIER(JSValue)
// Layout description.
static const int kValueOffset = JSObject::kHeaderSize;
@@ -6401,9 +6482,8 @@ class JSDate: public JSObject {
}
void JSDatePrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSDateVerify();
-#endif
+ DECLARE_VERIFIER(JSDate)
+
// The order is important. It must be kept in sync with date macros
// in macros.py.
enum FieldIndex {
@@ -6499,9 +6579,7 @@ class JSMessageObject: public JSObject {
}
void JSMessageObjectPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSMessageObjectVerify();
-#endif
+ DECLARE_VERIFIER(JSMessageObject)
// Layout description.
static const int kTypeOffset = JSObject::kHeaderSize;
@@ -6570,6 +6648,7 @@ class JSRegExp: public JSObject {
inline Object* DataAtUnchecked(int index);
inline void SetDataAtUnchecked(int index, Object* value, Heap* heap);
inline Type TypeTagUnchecked();
+ inline void ResetLastIndex();
static int code_index(bool is_ascii) {
if (is_ascii) {
@@ -6590,9 +6669,7 @@ class JSRegExp: public JSObject {
static inline JSRegExp* cast(Object* obj);
// Dispatched behavior.
-#ifdef DEBUG
- void JSRegExpVerify();
-#endif
+ DECLARE_VERIFIER(JSRegExp)
static const int kDataOffset = JSObject::kHeaderSize;
static const int kSize = kDataOffset + kPointerSize;
@@ -6748,9 +6825,7 @@ class CodeCache: public Struct {
}
void CodeCachePrint(FILE* out);
#endif
-#ifdef DEBUG
- void CodeCacheVerify();
-#endif
+ DECLARE_VERIFIER(CodeCache)
static const int kDefaultCacheOffset = HeapObject::kHeaderSize;
static const int kNormalTypeCacheOffset =
@@ -6839,9 +6914,7 @@ class PolymorphicCodeCache: public Struct {
}
void PolymorphicCodeCachePrint(FILE* out);
#endif
-#ifdef DEBUG
- void PolymorphicCodeCacheVerify();
-#endif
+ DECLARE_VERIFIER(PolymorphicCodeCache)
static const int kCacheOffset = HeapObject::kHeaderSize;
static const int kSize = kCacheOffset + kPointerSize;
@@ -6894,9 +6967,7 @@ class TypeFeedbackInfo: public Struct {
}
void TypeFeedbackInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void TypeFeedbackInfoVerify();
-#endif
+ DECLARE_VERIFIER(TypeFeedbackInfo)
static const int kStorage1Offset = HeapObject::kHeaderSize;
static const int kStorage2Offset = kStorage1Offset + kPointerSize;
@@ -6942,9 +7013,7 @@ class AliasedArgumentsEntry: public Struct {
}
void AliasedArgumentsEntryPrint(FILE* out);
#endif
-#ifdef DEBUG
- void AliasedArgumentsEntryVerify();
-#endif
+ DECLARE_VERIFIER(AliasedArgumentsEntry)
static const int kAliasedContextSlot = HeapObject::kHeaderSize;
static const int kSize = kAliasedContextSlot + kPointerSize;
@@ -6987,10 +7056,6 @@ class StringHasher {
// index.
bool is_array_index() { return is_array_index_; }
- bool is_valid() { return is_valid_; }
-
- void invalidate() { is_valid_ = false; }
-
// Calculated hash value for a string consisting of 1 to
// String::kMaxArrayIndexSize digits with no leading zeros (except "0").
// value is represented decimal value.
@@ -7009,13 +7074,33 @@ class StringHasher {
inline uint32_t GetHash();
+ // Reusable parts of the hashing algorithm.
+ INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint32_t c));
+ INLINE(static uint32_t GetHashCore(uint32_t running_hash));
+
int length_;
uint32_t raw_running_hash_;
uint32_t array_index_;
bool is_array_index_;
bool is_first_char_;
- bool is_valid_;
friend class TwoCharHashTableKey;
+
+ template <bool seq_ascii> friend class JsonParser;
+};
+
+
+class IncrementalAsciiStringHasher {
+ public:
+ explicit inline IncrementalAsciiStringHasher(uint32_t seed, char first_char);
+ inline void AddCharacter(uc32 c);
+ inline uint32_t GetHash();
+
+ private:
+ int length_;
+ uint32_t raw_running_hash_;
+ uint32_t array_index_;
+ bool is_array_index_;
+ char first_char_;
};
@@ -7085,6 +7170,8 @@ class StringShape BASE_EMBEDDED {
// All string values have a length field.
class String: public HeapObject {
public:
+ enum Encoding { ONE_BYTE_ENCODING, TWO_BYTE_ENCODING };
+
// Representation of the flat content of a String.
// A non-flat string doesn't have flat content.
// A flat string has content that's encoded as a sequence of either
@@ -7142,13 +7229,13 @@ class String: public HeapObject {
// be ASCII encoded. This might be the case even if the string is
// two-byte. Such strings may appear when the embedder prefers
// two-byte external representations even for ASCII data.
- inline bool IsAsciiRepresentation();
+ inline bool IsOneByteRepresentation();
inline bool IsTwoByteRepresentation();
// Cons and slices have an encoding flag that may not represent the actual
// encoding of the underlying string. This is taken into account here.
// Requires: this->IsFlat()
- inline bool IsAsciiRepresentationUnderneath();
+ inline bool IsOneByteRepresentationUnderneath();
inline bool IsTwoByteRepresentationUnderneath();
// NOTE: this should be considered only a hint. False negatives are
@@ -7275,9 +7362,8 @@ class String: public HeapObject {
char* ToAsciiArray();
#endif
-#ifdef DEBUG
- void StringVerify();
-#endif
+ DECLARE_VERIFIER(String)
+
inline bool IsFlat();
// Layout description.
@@ -7346,7 +7432,7 @@ class String: public HeapObject {
kIsNotArrayIndexMask | kHashNotComputedMask;
// Value of hash field containing computed hash equal to zero.
- static const int kZeroHash = kIsNotArrayIndexMask;
+ static const int kEmptyStringHash = kIsNotArrayIndexMask;
// Maximal string length.
static const int kMaxLength = (1 << (32 - 2)) - 1;
@@ -7381,34 +7467,57 @@ class String: public HeapObject {
int from,
int to);
- static inline bool IsAscii(const char* chars, int length) {
+ // The return value may point to the first aligned word containing the
+ // first non-ascii character, rather than directly to the non-ascii character.
+ // If the return value is >= the passed length, the entire string was ASCII.
+ static inline int NonAsciiStart(const char* chars, int length) {
+ const char* start = chars;
const char* limit = chars + length;
#ifdef V8_HOST_CAN_READ_UNALIGNED
ASSERT(kMaxAsciiCharCode == 0x7F);
const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80;
while (chars + sizeof(uintptr_t) <= limit) {
if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) {
- return false;
+ return static_cast<int>(chars - start);
}
chars += sizeof(uintptr_t);
}
#endif
while (chars < limit) {
- if (static_cast<uint8_t>(*chars) > kMaxAsciiCharCodeU) return false;
+ if (static_cast<uint8_t>(*chars) > kMaxAsciiCharCodeU) {
+ return static_cast<int>(chars - start);
+ }
++chars;
}
- return true;
+ return static_cast<int>(chars - start);
}
- static inline bool IsAscii(const uc16* chars, int length) {
+ static inline bool IsAscii(const char* chars, int length) {
+ return NonAsciiStart(chars, length) >= length;
+ }
+
+ static inline int NonAsciiStart(const uc16* chars, int length) {
const uc16* limit = chars + length;
+ const uc16* start = chars;
while (chars < limit) {
- if (*chars > kMaxAsciiCharCodeU) return false;
+ if (*chars > kMaxAsciiCharCodeU) return static_cast<int>(chars - start);
++chars;
}
- return true;
+ return static_cast<int>(chars - start);
+ }
+
+ static inline bool IsAscii(const uc16* chars, int length) {
+ return NonAsciiStart(chars, length) >= length;
}
+ template<class Visitor, class ConsOp>
+ static inline void Visit(String* string,
+ unsigned offset,
+ Visitor& visitor,
+ ConsOp& consOp,
+ int32_t type,
+ unsigned length);
+
protected:
class ReadBlockBuffer {
public:
@@ -7467,6 +7576,11 @@ class SeqString: public String {
// Layout description.
static const int kHeaderSize = String::kSize;
+ // Truncate the string in-place if possible and return the result.
+ // In case of new_length == 0, the empty string is returned without
+ // truncating the original string.
+ MUST_USE_RESULT String* Truncate(int new_length);
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
};
@@ -7474,13 +7588,13 @@ class SeqString: public String {
// The AsciiString class captures sequential ASCII string objects.
// Each character in the AsciiString is an ASCII character.
-class SeqAsciiString: public SeqString {
+class SeqOneByteString: public SeqString {
public:
static const bool kHasAsciiEncoding = true;
// Dispatched behavior.
- inline uint16_t SeqAsciiStringGet(int index);
- inline void SeqAsciiStringSet(int index, uint16_t value);
+ inline uint16_t SeqOneByteStringGet(int index);
+ inline void SeqOneByteStringSet(int index, uint16_t value);
// Get the address of the characters in this string.
inline Address GetCharsAddress();
@@ -7488,12 +7602,12 @@ class SeqAsciiString: public SeqString {
inline char* GetChars();
// Casting
- static inline SeqAsciiString* cast(Object* obj);
+ static inline SeqOneByteString* cast(Object* obj);
// Garbage collection support. This method is called by the
// garbage collector to compute the actual size of an AsciiString
// instance.
- inline int SeqAsciiStringSize(InstanceType instance_type);
+ inline int SeqOneByteStringSize(InstanceType instance_type);
// Computes the size for an AsciiString instance of a given length.
static int SizeFor(int length) {
@@ -7507,19 +7621,17 @@ class SeqAsciiString: public SeqString {
static const int kMaxLength = (kMaxSize - kHeaderSize);
// Support for StringInputBuffer.
- inline void SeqAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
+ inline void SeqOneByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
unsigned* offset,
unsigned chars);
- inline const unibrow::byte* SeqAsciiStringReadBlock(unsigned* remaining,
+ inline const unibrow::byte* SeqOneByteStringReadBlock(unsigned* remaining,
unsigned* offset,
unsigned chars);
-#ifdef DEBUG
- void SeqAsciiStringVerify();
-#endif
+ DECLARE_VERIFIER(SeqOneByteString)
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(SeqAsciiString);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
};
@@ -7621,9 +7733,7 @@ class ConsString: public String {
typedef FixedBodyDescriptor<kFirstOffset, kSecondOffset + kPointerSize, kSize>
BodyDescriptor;
-#ifdef DEBUG
- void ConsStringVerify();
-#endif
+ DECLARE_VERIFIER(ConsString)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ConsString);
@@ -7675,9 +7785,7 @@ class SlicedString: public String {
kOffsetOffset + kPointerSize, kSize>
BodyDescriptor;
-#ifdef DEBUG
- void SlicedStringVerify();
-#endif
+ DECLARE_VERIFIER(SlicedString)
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(SlicedString);
@@ -7864,14 +7972,75 @@ class StringInputBuffer: public unibrow::InputBuffer<String, String*, 1024> {
};
-class SafeStringInputBuffer
- : public unibrow::InputBuffer<String, String**, 256> {
+// This maintains an off-stack representation of the stack frames required
+// to traverse a ConsString, allowing an entirely iterative and restartable
+// traversal of the entire string
+// Note: this class is not GC-safe.
+class ConsStringIteratorOp {
public:
- virtual void Seek(unsigned pos);
- inline SafeStringInputBuffer()
- : unibrow::InputBuffer<String, String**, 256>() {}
- explicit inline SafeStringInputBuffer(String** backing)
- : unibrow::InputBuffer<String, String**, 256>(backing) {}
+ struct ContinueResponse {
+ String* string_;
+ unsigned offset_;
+ unsigned length_;
+ int32_t type_;
+ };
+ inline ConsStringIteratorOp() {}
+ String* Operate(ConsString* consString, unsigned* outerOffset,
+ int32_t* typeOut, unsigned* lengthOut);
+ inline bool ContinueOperation(ContinueResponse* response);
+ inline void Reset();
+ inline bool HasMore();
+
+ private:
+ // TODO(dcarney): Templatize this out for different stack sizes.
+ static const unsigned kStackSize = 32;
+ // Use a mask instead of doing modulo operations for stack wrapping.
+ static const unsigned kDepthMask = kStackSize-1;
+ STATIC_ASSERT(IS_POWER_OF_TWO(kStackSize));
+ static inline unsigned OffsetForDepth(unsigned depth);
+ static inline uint32_t MaskForDepth(unsigned depth);
+
+ inline void ClearRightDescent();
+ inline void SetRightDescent();
+ inline void PushLeft(ConsString* string);
+ inline void PushRight(ConsString* string, int32_t type);
+ inline void AdjustMaximumDepth();
+ inline void Pop();
+ inline void ResetStack();
+ String* NextLeaf(bool* blewStack, int32_t* typeOut);
+
+ unsigned depth_;
+ unsigned maximum_depth_;
+ uint32_t trace_;
+ ConsString* frames_[kStackSize];
+ unsigned consumed_;
+ ConsString* root_;
+ int32_t root_type_;
+ unsigned root_length_;
+ DISALLOW_COPY_AND_ASSIGN(ConsStringIteratorOp);
+};
+
+
+// Note: this class is not GC-safe.
+class StringCharacterStream {
+ public:
+ inline StringCharacterStream(
+ String* string, unsigned offset, ConsStringIteratorOp* op);
+ inline uint16_t GetNext();
+ inline bool HasMore();
+ inline void Reset(String* string, unsigned offset, ConsStringIteratorOp* op);
+ inline void VisitOneByteString(const uint8_t* chars, unsigned length);
+ inline void VisitTwoByteString(const uint16_t* chars, unsigned length);
+
+ private:
+ bool is_one_byte_;
+ union {
+ const uint8_t* buffer8_;
+ const uint16_t* buffer16_;
+ };
+ const uint8_t* end_;
+ ConsStringIteratorOp* op_;
+ DISALLOW_COPY_AND_ASSIGN(StringCharacterStream);
};
@@ -7904,9 +8073,7 @@ class Oddball: public HeapObject {
static inline Oddball* cast(Object* obj);
// Dispatched behavior.
-#ifdef DEBUG
- void OddballVerify();
-#endif
+ DECLARE_VERIFIER(Oddball)
// Initialize the fields.
MUST_USE_RESULT MaybeObject* Initialize(const char* to_string,
@@ -7957,9 +8124,8 @@ class JSGlobalPropertyCell: public HeapObject {
return address() + kValueOffset;
}
-#ifdef DEBUG
- void JSGlobalPropertyCellVerify();
-#endif
+ DECLARE_VERIFIER(JSGlobalPropertyCell)
+
#ifdef OBJECT_PRINT
inline void JSGlobalPropertyCellPrint() {
JSGlobalPropertyCellPrint(stdout);
@@ -8062,9 +8228,7 @@ class JSProxy: public JSReceiver {
}
void JSProxyPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSProxyVerify();
-#endif
+ DECLARE_VERIFIER(JSProxy)
// Layout description. We add padding so that a proxy has the same
// size as a virgin JSObject. This is essential for becoming a JSObject
@@ -8105,9 +8269,7 @@ class JSFunctionProxy: public JSProxy {
}
void JSFunctionProxyPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSFunctionProxyVerify();
-#endif
+ DECLARE_VERIFIER(JSFunctionProxy)
// Layout description.
static const int kCallTrapOffset = JSProxy::kPaddingOffset;
@@ -8142,9 +8304,7 @@ class JSSet: public JSObject {
}
void JSSetPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSSetVerify();
-#endif
+ DECLARE_VERIFIER(JSSet)
static const int kTableOffset = JSObject::kHeaderSize;
static const int kSize = kTableOffset + kPointerSize;
@@ -8169,9 +8329,7 @@ class JSMap: public JSObject {
}
void JSMapPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSMapVerify();
-#endif
+ DECLARE_VERIFIER(JSMap)
static const int kTableOffset = JSObject::kHeaderSize;
static const int kSize = kTableOffset + kPointerSize;
@@ -8199,9 +8357,7 @@ class JSWeakMap: public JSObject {
}
void JSWeakMapPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSWeakMapVerify();
-#endif
+ DECLARE_VERIFIER(JSWeakMap)
static const int kTableOffset = JSObject::kHeaderSize;
static const int kNextOffset = kTableOffset + kPointerSize;
@@ -8236,9 +8392,7 @@ class Foreign: public HeapObject {
}
void ForeignPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ForeignVerify();
-#endif
+ DECLARE_VERIFIER(Foreign)
// Layout description.
@@ -8276,6 +8430,7 @@ class JSArray: public JSObject {
// Initializes the array to a certain length.
inline bool AllowsSetElementsLength();
+ // Can cause GC.
MUST_USE_RESULT MaybeObject* SetElementsLength(Object* length);
// Set the content of the array to the content of storage.
@@ -8295,9 +8450,7 @@ class JSArray: public JSObject {
}
void JSArrayPrint(FILE* out);
#endif
-#ifdef DEBUG
- void JSArrayVerify();
-#endif
+ DECLARE_VERIFIER(JSArray)
// Number of element slots to pre-allocate for an empty array.
static const int kPreallocatedArrayElements = 4;
@@ -8376,9 +8529,7 @@ class AccessorInfo: public Struct {
}
void AccessorInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void AccessorInfoVerify();
-#endif
+ DECLARE_VERIFIER(AccessorInfo)
static const int kGetterOffset = HeapObject::kHeaderSize;
static const int kSetterOffset = kGetterOffset + kPointerSize;
@@ -8442,9 +8593,7 @@ class AccessorPair: public Struct {
#ifdef OBJECT_PRINT
void AccessorPairPrint(FILE* out = stdout);
#endif
-#ifdef DEBUG
- void AccessorPairVerify();
-#endif
+ DECLARE_VERIFIER(AccessorPair)
static const int kGetterOffset = HeapObject::kHeaderSize;
static const int kSetterOffset = kGetterOffset + kPointerSize;
@@ -8478,9 +8627,7 @@ class AccessCheckInfo: public Struct {
}
void AccessCheckInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void AccessCheckInfoVerify();
-#endif
+ DECLARE_VERIFIER(AccessCheckInfo)
static const int kNamedCallbackOffset = HeapObject::kHeaderSize;
static const int kIndexedCallbackOffset = kNamedCallbackOffset + kPointerSize;
@@ -8509,9 +8656,7 @@ class InterceptorInfo: public Struct {
}
void InterceptorInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void InterceptorInfoVerify();
-#endif
+ DECLARE_VERIFIER(InterceptorInfo)
static const int kGetterOffset = HeapObject::kHeaderSize;
static const int kSetterOffset = kGetterOffset + kPointerSize;
@@ -8539,9 +8684,7 @@ class CallHandlerInfo: public Struct {
}
void CallHandlerInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void CallHandlerInfoVerify();
-#endif
+ DECLARE_VERIFIER(CallHandlerInfo)
static const int kCallbackOffset = HeapObject::kHeaderSize;
static const int kDataOffset = kCallbackOffset + kPointerSize;
@@ -8557,9 +8700,7 @@ class TemplateInfo: public Struct {
DECL_ACCESSORS(tag, Object)
DECL_ACCESSORS(property_list, Object)
-#ifdef DEBUG
- void TemplateInfoVerify();
-#endif
+ DECLARE_VERIFIER(TemplateInfo)
static const int kTagOffset = HeapObject::kHeaderSize;
static const int kPropertyListOffset = kTagOffset + kPointerSize;
@@ -8602,9 +8743,7 @@ class FunctionTemplateInfo: public TemplateInfo {
}
void FunctionTemplateInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void FunctionTemplateInfoVerify();
-#endif
+ DECLARE_VERIFIER(FunctionTemplateInfo)
static const int kSerialNumberOffset = TemplateInfo::kHeaderSize;
static const int kCallCodeOffset = kSerialNumberOffset + kPointerSize;
@@ -8651,9 +8790,7 @@ class ObjectTemplateInfo: public TemplateInfo {
}
void ObjectTemplateInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void ObjectTemplateInfoVerify();
-#endif
+ DECLARE_VERIFIER(ObjectTemplateInfo)
static const int kConstructorOffset = TemplateInfo::kHeaderSize;
static const int kInternalFieldCountOffset =
@@ -8675,9 +8812,7 @@ class SignatureInfo: public Struct {
}
void SignatureInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void SignatureInfoVerify();
-#endif
+ DECLARE_VERIFIER(SignatureInfo)
static const int kReceiverOffset = Struct::kHeaderSize;
static const int kArgsOffset = kReceiverOffset + kPointerSize;
@@ -8700,9 +8835,7 @@ class TypeSwitchInfo: public Struct {
}
void TypeSwitchInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void TypeSwitchInfoVerify();
-#endif
+ DECLARE_VERIFIER(TypeSwitchInfo)
static const int kTypesOffset = Struct::kHeaderSize;
static const int kSize = kTypesOffset + kPointerSize;
@@ -8752,9 +8885,7 @@ class DebugInfo: public Struct {
}
void DebugInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void DebugInfoVerify();
-#endif
+ DECLARE_VERIFIER(DebugInfo)
static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
static const int kOriginalCodeIndex = kSharedFunctionInfoIndex + kPointerSize;
@@ -8810,9 +8941,7 @@ class BreakPointInfo: public Struct {
}
void BreakPointInfoPrint(FILE* out);
#endif
-#ifdef DEBUG
- void BreakPointInfoVerify();
-#endif
+ DECLARE_VERIFIER(BreakPointInfo)
static const int kCodePositionIndex = Struct::kHeaderSize;
static const int kSourcePositionIndex = kCodePositionIndex + kPointerSize;
@@ -8830,6 +8959,7 @@ class BreakPointInfo: public Struct {
#undef DECL_BOOLEAN_ACCESSORS
#undef DECL_ACCESSORS
+#undef DECLARE_VERIFIER
#define VISITOR_SYNCHRONIZATION_TAGS_LIST(V) \
V(kSymbolTable, "symbol_table", "(Symbols)") \
@@ -8894,6 +9024,10 @@ class ObjectVisitor BASE_EMBEDDED {
// Visits a debug call target in the instruction stream.
virtual void VisitDebugTarget(RelocInfo* rinfo);
+ // Visits the byte sequence in a function's prologue that contains information
+ // about the code's age.
+ virtual void VisitCodeAgeSequence(RelocInfo* rinfo);
+
// Handy shorthand for visiting a single pointer.
virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }