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.h2244
1 files changed, 1276 insertions, 968 deletions
diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h
index 755dd42d9e..933a07599a 100644
--- a/deps/v8/src/objects.h
+++ b/deps/v8/src/objects.h
@@ -77,7 +77,7 @@
// - DescriptorArray
// - HashTable
// - Dictionary
-// - SymbolTable
+// - StringTable
// - CompilationCacheTable
// - CodeCacheHashTable
// - MapCache
@@ -95,15 +95,25 @@
// - ExternalIntArray
// - ExternalUnsignedIntArray
// - ExternalFloatArray
-// - String
-// - SeqString
-// - SeqAsciiString
-// - SeqTwoByteString
-// - SlicedString
-// - ConsString
-// - ExternalString
-// - ExternalAsciiString
-// - ExternalTwoByteString
+// - Name
+// - String
+// - SeqString
+// - SeqOneByteString
+// - SeqTwoByteString
+// - SlicedString
+// - ConsString
+// - ExternalString
+// - ExternalAsciiString
+// - ExternalTwoByteString
+// - InternalizedString
+// - SeqInternalizedString
+// - SeqOneByteInternalizedString
+// - SeqTwoByteInternalizedString
+// - ConsInternalizedString
+// - ExternalInternalizedString
+// - ExternalAsciiInternalizedString
+// - ExternalTwoByteInternalizedString
+// - Symbol
// - HeapNumber
// - Code
// - Map
@@ -111,7 +121,10 @@
// - Foreign
// - SharedFunctionInfo
// - Struct
+// - DeclaredAccessorDescriptor
// - AccessorInfo
+// - DeclaredAccessorInfo
+// - ExecutableAccessorInfo
// - AccessorPair
// - AccessCheckInfo
// - InterceptorInfo
@@ -139,11 +152,75 @@ enum CompareMapMode {
ALLOW_ELEMENT_TRANSITION_MAPS
};
-enum KeyedAccessGrowMode {
- DO_NOT_ALLOW_JSARRAY_GROWTH,
- ALLOW_JSARRAY_GROWTH
+enum KeyedAccessStoreMode {
+ STANDARD_STORE,
+ STORE_TRANSITION_SMI_TO_OBJECT,
+ STORE_TRANSITION_SMI_TO_DOUBLE,
+ STORE_TRANSITION_DOUBLE_TO_OBJECT,
+ STORE_TRANSITION_HOLEY_SMI_TO_OBJECT,
+ STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE,
+ STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT,
+ STORE_AND_GROW_NO_TRANSITION,
+ STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT,
+ STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE,
+ STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT,
+ STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT,
+ STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE,
+ STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT,
+ STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS,
+ STORE_NO_TRANSITION_HANDLE_COW
};
+
+static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION -
+ STANDARD_STORE;
+STATIC_ASSERT(STANDARD_STORE == 0);
+STATIC_ASSERT(kGrowICDelta ==
+ STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT -
+ STORE_TRANSITION_SMI_TO_OBJECT);
+STATIC_ASSERT(kGrowICDelta ==
+ STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE -
+ STORE_TRANSITION_SMI_TO_DOUBLE);
+STATIC_ASSERT(kGrowICDelta ==
+ STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT -
+ STORE_TRANSITION_DOUBLE_TO_OBJECT);
+
+
+static inline KeyedAccessStoreMode GetGrowStoreMode(
+ KeyedAccessStoreMode store_mode) {
+ if (store_mode < STORE_AND_GROW_NO_TRANSITION) {
+ store_mode = static_cast<KeyedAccessStoreMode>(
+ static_cast<int>(store_mode) + kGrowICDelta);
+ }
+ return store_mode;
+}
+
+
+static inline bool IsTransitionStoreMode(KeyedAccessStoreMode store_mode) {
+ return store_mode > STANDARD_STORE &&
+ store_mode <= STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT &&
+ store_mode != STORE_AND_GROW_NO_TRANSITION;
+}
+
+
+static inline KeyedAccessStoreMode GetNonTransitioningStoreMode(
+ KeyedAccessStoreMode store_mode) {
+ if (store_mode >= STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
+ return store_mode;
+ }
+ if (store_mode >= STORE_AND_GROW_NO_TRANSITION) {
+ return STORE_AND_GROW_NO_TRANSITION;
+ }
+ return STANDARD_STORE;
+}
+
+
+static inline bool IsGrowStoreMode(KeyedAccessStoreMode store_mode) {
+ return store_mode >= STORE_AND_GROW_NO_TRANSITION &&
+ store_mode <= STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT;
+}
+
+
// Setter that skips the write barrier if mode is SKIP_WRITE_BARRIER.
enum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER };
@@ -178,6 +255,12 @@ enum TransitionFlag {
};
+enum DebugExtraICState {
+ DEBUG_BREAK,
+ DEBUG_PREPARE_STEP_IN
+};
+
+
// 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.
@@ -194,6 +277,18 @@ enum DescriptorFlag {
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;
@@ -213,8 +308,8 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
// encoding is mentioned explicitly in the name. Likewise, the default
// representation is considered sequential. It is not mentioned in the
// name. The other representations (e.g. CONS, EXTERNAL) are explicitly
-// mentioned. Finally, the string is either a SYMBOL_TYPE (if it is a
-// symbol) or a STRING_TYPE (if it is not a symbol).
+// mentioned. Finally, the string is either a STRING_TYPE (if it is a normal
+// string) or a INTERNALIZED_STRING_TYPE (if it is a internalized string).
//
// NOTE: The following things are some that depend on the string types having
// instance_types that are less than those of all other types:
@@ -225,29 +320,30 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
// JSObject for GC purposes. The first four entries here have typeof
// 'object', whereas JS_FUNCTION_TYPE has typeof 'function'.
#define INSTANCE_TYPE_LIST_ALL(V) \
- V(SYMBOL_TYPE) \
- V(ASCII_SYMBOL_TYPE) \
- V(CONS_SYMBOL_TYPE) \
- V(CONS_ASCII_SYMBOL_TYPE) \
- V(EXTERNAL_SYMBOL_TYPE) \
- V(EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE) \
- V(EXTERNAL_ASCII_SYMBOL_TYPE) \
- V(SHORT_EXTERNAL_SYMBOL_TYPE) \
- V(SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE) \
- V(SHORT_EXTERNAL_ASCII_SYMBOL_TYPE) \
V(STRING_TYPE) \
V(ASCII_STRING_TYPE) \
V(CONS_STRING_TYPE) \
V(CONS_ASCII_STRING_TYPE) \
V(SLICED_STRING_TYPE) \
V(EXTERNAL_STRING_TYPE) \
- V(EXTERNAL_STRING_WITH_ASCII_DATA_TYPE) \
V(EXTERNAL_ASCII_STRING_TYPE) \
+ V(EXTERNAL_STRING_WITH_ASCII_DATA_TYPE) \
V(SHORT_EXTERNAL_STRING_TYPE) \
- V(SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE) \
V(SHORT_EXTERNAL_ASCII_STRING_TYPE) \
- V(PRIVATE_EXTERNAL_ASCII_STRING_TYPE) \
+ V(SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE) \
+ \
+ V(INTERNALIZED_STRING_TYPE) \
+ V(ASCII_INTERNALIZED_STRING_TYPE) \
+ V(CONS_INTERNALIZED_STRING_TYPE) \
+ V(CONS_ASCII_INTERNALIZED_STRING_TYPE) \
+ V(EXTERNAL_INTERNALIZED_STRING_TYPE) \
+ V(EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE) \
+ V(EXTERNAL_INTERNALIZED_STRING_WITH_ASCII_DATA_TYPE) \
+ V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE) \
+ V(SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE) \
+ V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ASCII_DATA_TYPE) \
\
+ V(SYMBOL_TYPE) \
V(MAP_TYPE) \
V(CODE_TYPE) \
V(ODDBALL_TYPE) \
@@ -270,7 +366,9 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
V(EXTERNAL_PIXEL_ARRAY_TYPE) \
V(FILLER_TYPE) \
\
- V(ACCESSOR_INFO_TYPE) \
+ V(DECLARED_ACCESSOR_DESCRIPTOR_TYPE) \
+ V(DECLARED_ACCESSOR_INFO_TYPE) \
+ V(EXECUTABLE_ACCESSOR_INFO_TYPE) \
V(ACCESSOR_PAIR_TYPE) \
V(ACCESS_CHECK_INFO_TYPE) \
V(INTERCEPTOR_INFO_TYPE) \
@@ -279,6 +377,7 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
V(OBJECT_TEMPLATE_INFO_TYPE) \
V(SIGNATURE_INFO_TYPE) \
V(TYPE_SWITCH_INFO_TYPE) \
+ V(ALLOCATION_SITE_INFO_TYPE) \
V(SCRIPT_TYPE) \
V(CODE_CACHE_TYPE) \
V(POLYMORPHIC_CODE_CACHE_TYPE) \
@@ -323,46 +422,6 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
// Since string types are not consecutive, this macro is used to
// iterate over them.
#define STRING_TYPE_LIST(V) \
- V(SYMBOL_TYPE, \
- kVariableSizeSentinel, \
- symbol, \
- Symbol) \
- V(ASCII_SYMBOL_TYPE, \
- kVariableSizeSentinel, \
- ascii_symbol, \
- AsciiSymbol) \
- V(CONS_SYMBOL_TYPE, \
- ConsString::kSize, \
- cons_symbol, \
- ConsSymbol) \
- V(CONS_ASCII_SYMBOL_TYPE, \
- ConsString::kSize, \
- cons_ascii_symbol, \
- ConsAsciiSymbol) \
- V(EXTERNAL_SYMBOL_TYPE, \
- ExternalTwoByteString::kSize, \
- external_symbol, \
- ExternalSymbol) \
- V(EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE, \
- ExternalTwoByteString::kSize, \
- external_symbol_with_ascii_data, \
- ExternalSymbolWithAsciiData) \
- V(EXTERNAL_ASCII_SYMBOL_TYPE, \
- ExternalAsciiString::kSize, \
- external_ascii_symbol, \
- ExternalAsciiSymbol) \
- V(SHORT_EXTERNAL_SYMBOL_TYPE, \
- ExternalTwoByteString::kShortSize, \
- short_external_symbol, \
- ShortExternalSymbol) \
- V(SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE, \
- ExternalTwoByteString::kShortSize, \
- short_external_symbol_with_ascii_data, \
- ShortExternalSymbolWithAsciiData) \
- V(SHORT_EXTERNAL_ASCII_SYMBOL_TYPE, \
- ExternalAsciiString::kShortSize, \
- short_external_ascii_symbol, \
- ShortExternalAsciiSymbol) \
V(STRING_TYPE, \
kVariableSizeSentinel, \
string, \
@@ -391,26 +450,67 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
ExternalTwoByteString::kSize, \
external_string, \
ExternalString) \
- V(EXTERNAL_STRING_WITH_ASCII_DATA_TYPE, \
- ExternalTwoByteString::kSize, \
- external_string_with_ascii_data, \
- ExternalStringWithAsciiData) \
V(EXTERNAL_ASCII_STRING_TYPE, \
ExternalAsciiString::kSize, \
external_ascii_string, \
ExternalAsciiString) \
+ V(EXTERNAL_STRING_WITH_ASCII_DATA_TYPE, \
+ ExternalTwoByteString::kSize, \
+ external_string_with_ascii_data, \
+ ExternalStringWithAsciiData) \
V(SHORT_EXTERNAL_STRING_TYPE, \
ExternalTwoByteString::kShortSize, \
short_external_string, \
ShortExternalString) \
+ V(SHORT_EXTERNAL_ASCII_STRING_TYPE, \
+ ExternalAsciiString::kShortSize, \
+ short_external_ascii_string, \
+ ShortExternalAsciiString) \
V(SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE, \
ExternalTwoByteString::kShortSize, \
short_external_string_with_ascii_data, \
ShortExternalStringWithAsciiData) \
- V(SHORT_EXTERNAL_ASCII_STRING_TYPE, \
+ \
+ V(INTERNALIZED_STRING_TYPE, \
+ kVariableSizeSentinel, \
+ internalized_string, \
+ InternalizedString) \
+ V(ASCII_INTERNALIZED_STRING_TYPE, \
+ kVariableSizeSentinel, \
+ ascii_internalized_string, \
+ AsciiInternalizedString) \
+ V(CONS_INTERNALIZED_STRING_TYPE, \
+ ConsString::kSize, \
+ cons_internalized_string, \
+ ConsInternalizedString) \
+ V(CONS_ASCII_INTERNALIZED_STRING_TYPE, \
+ ConsString::kSize, \
+ cons_ascii_internalized_string, \
+ ConsAsciiInternalizedString) \
+ V(EXTERNAL_INTERNALIZED_STRING_TYPE, \
+ ExternalTwoByteString::kSize, \
+ external_internalized_string, \
+ ExternalInternalizedString) \
+ V(EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE, \
+ ExternalAsciiString::kSize, \
+ external_ascii_internalized_string, \
+ ExternalAsciiInternalizedString) \
+ V(EXTERNAL_INTERNALIZED_STRING_WITH_ASCII_DATA_TYPE, \
+ ExternalTwoByteString::kSize, \
+ external_internalized_string_with_ascii_data, \
+ ExternalInternalizedStringWithAsciiData) \
+ V(SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE, \
+ ExternalTwoByteString::kShortSize, \
+ short_external_internalized_string, \
+ ShortExternalInternalizedString) \
+ V(SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE, \
ExternalAsciiString::kShortSize, \
- short_external_ascii_string, \
- ShortExternalAsciiString)
+ short_external_ascii_internalized_string, \
+ ShortExternalAsciiInternalizedString) \
+ V(SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ASCII_DATA_TYPE, \
+ ExternalTwoByteString::kShortSize, \
+ short_external_internalized_string_with_ascii_data, \
+ ShortExternalInternalizedStringWithAsciiData) \
// A struct is a simple object a set of object-valued fields. Including an
// object type in this causes the compiler to generate most of the boilerplate
@@ -422,7 +522,11 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
// type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
// manually.
#define STRUCT_LIST_ALL(V) \
- V(ACCESSOR_INFO, AccessorInfo, accessor_info) \
+ V(DECLARED_ACCESSOR_DESCRIPTOR, \
+ DeclaredAccessorDescriptor, \
+ declared_accessor_descriptor) \
+ V(DECLARED_ACCESSOR_INFO, DeclaredAccessorInfo, declared_accessor_info) \
+ V(EXECUTABLE_ACCESSOR_INFO, ExecutableAccessorInfo, executable_accessor_info)\
V(ACCESSOR_PAIR, AccessorPair, accessor_pair) \
V(ACCESS_CHECK_INFO, AccessCheckInfo, access_check_info) \
V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info) \
@@ -432,6 +536,7 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
V(SIGNATURE_INFO, SignatureInfo, signature_info) \
V(TYPE_SWITCH_INFO, TypeSwitchInfo, type_switch_info) \
V(SCRIPT, Script, script) \
+ V(ALLOCATION_SITE_INFO, AllocationSiteInfo, allocation_site_info) \
V(CODE_CACHE, CodeCache, code_cache) \
V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache) \
V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info) \
@@ -456,18 +561,18 @@ const uint32_t kIsNotStringMask = 0x80;
const uint32_t kStringTag = 0x0;
const uint32_t kNotStringTag = 0x80;
-// Bit 6 indicates that the object is a symbol (if set) or not (if cleared).
+// Bit 6 indicates that the object is an internalized string (if set) or not.
// There are not enough types that the non-string types (with bit 7 set) can
// have bit 6 set too.
-const uint32_t kIsSymbolMask = 0x40;
-const uint32_t kNotSymbolTag = 0x0;
-const uint32_t kSymbolTag = 0x40;
+const uint32_t kIsInternalizedMask = 0x40;
+const uint32_t kNotInternalizedTag = 0x0;
+const uint32_t kInternalizedTag = 0x40;
// If bit 7 is clear then bit 2 indicates whether the string consists of
// 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.
@@ -504,57 +609,57 @@ const uint32_t kShortExternalStringTag = 0x10;
// A ConsString with an empty string as the right side is a candidate
-// for being shortcut by the garbage collector unless it is a
-// symbol. It's not common to have non-flat symbols, so we do not
-// shortcut them thereby avoiding turning symbols into strings. See
-// heap.cc and mark-compact.cc.
+// for being shortcut by the garbage collector unless it is internalized.
+// It's not common to have non-flat internalized strings, so we do not
+// shortcut them thereby avoiding turning internalized strings into strings.
+// See heap.cc and mark-compact.cc.
const uint32_t kShortcutTypeMask =
kIsNotStringMask |
- kIsSymbolMask |
+ kIsInternalizedMask |
kStringRepresentationMask;
const uint32_t kShortcutTypeTag = kConsStringTag;
enum InstanceType {
// String types.
- SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kSeqStringTag,
- ASCII_SYMBOL_TYPE = kAsciiStringTag | kSymbolTag | kSeqStringTag,
- CONS_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kConsStringTag,
- CONS_ASCII_SYMBOL_TYPE = kAsciiStringTag | 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,
- EXTERNAL_SYMBOL_TYPE = kTwoByteStringTag | kSymbolTag | kExternalStringTag,
- EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE =
- kTwoByteStringTag | kSymbolTag | kExternalStringTag | kAsciiDataHintTag,
- EXTERNAL_ASCII_SYMBOL_TYPE =
- kAsciiStringTag | kSymbolTag | kExternalStringTag,
STRING_TYPE = kTwoByteStringTag | kSeqStringTag,
- ASCII_STRING_TYPE = kAsciiStringTag | kSeqStringTag,
+ ASCII_STRING_TYPE = kOneByteStringTag | kSeqStringTag,
CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag,
- CONS_ASCII_STRING_TYPE = kAsciiStringTag | kConsStringTag,
+ CONS_ASCII_STRING_TYPE = kOneByteStringTag | kConsStringTag,
SLICED_STRING_TYPE = kTwoByteStringTag | kSlicedStringTag,
- SLICED_ASCII_STRING_TYPE = kAsciiStringTag | 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,
+ SLICED_ASCII_STRING_TYPE = kOneByteStringTag | kSlicedStringTag,
EXTERNAL_STRING_TYPE = kTwoByteStringTag | kExternalStringTag,
+ EXTERNAL_ASCII_STRING_TYPE = kOneByteStringTag | kExternalStringTag,
EXTERNAL_STRING_WITH_ASCII_DATA_TYPE =
- kTwoByteStringTag | kExternalStringTag | kAsciiDataHintTag,
- // LAST_STRING_TYPE
- EXTERNAL_ASCII_STRING_TYPE = kAsciiStringTag | kExternalStringTag,
- PRIVATE_EXTERNAL_ASCII_STRING_TYPE = EXTERNAL_ASCII_STRING_TYPE,
+ EXTERNAL_STRING_TYPE | kAsciiDataHintTag,
+ SHORT_EXTERNAL_STRING_TYPE = EXTERNAL_STRING_TYPE | kShortExternalStringTag,
+ SHORT_EXTERNAL_ASCII_STRING_TYPE =
+ EXTERNAL_ASCII_STRING_TYPE | kShortExternalStringTag,
+ SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE =
+ EXTERNAL_STRING_WITH_ASCII_DATA_TYPE | kShortExternalStringTag,
+
+ INTERNALIZED_STRING_TYPE = STRING_TYPE | kInternalizedTag,
+ ASCII_INTERNALIZED_STRING_TYPE = ASCII_STRING_TYPE | kInternalizedTag,
+ CONS_INTERNALIZED_STRING_TYPE = CONS_STRING_TYPE | kInternalizedTag,
+ CONS_ASCII_INTERNALIZED_STRING_TYPE =
+ CONS_ASCII_STRING_TYPE | kInternalizedTag,
+ EXTERNAL_INTERNALIZED_STRING_TYPE = EXTERNAL_STRING_TYPE | kInternalizedTag,
+ EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE =
+ EXTERNAL_ASCII_STRING_TYPE | kInternalizedTag,
+ EXTERNAL_INTERNALIZED_STRING_WITH_ASCII_DATA_TYPE =
+ EXTERNAL_STRING_WITH_ASCII_DATA_TYPE | kInternalizedTag,
+ SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE =
+ SHORT_EXTERNAL_STRING_TYPE | kInternalizedTag,
+ SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE =
+ SHORT_EXTERNAL_ASCII_STRING_TYPE | kInternalizedTag,
+ SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ASCII_DATA_TYPE =
+ SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE | kInternalizedTag,
+
+ // Non-string names
+ SYMBOL_TYPE = kNotStringTag, // LAST_NAME_TYPE, FIRST_NONSTRING_TYPE
// Objects allocated in their own spaces (never in new space).
- MAP_TYPE = kNotStringTag, // FIRST_NONSTRING_TYPE
+ MAP_TYPE,
CODE_TYPE,
ODDBALL_TYPE,
JS_GLOBAL_PROPERTY_CELL_TYPE,
@@ -578,7 +683,9 @@ enum InstanceType {
FILLER_TYPE, // LAST_DATA_TYPE
// Structs.
- ACCESSOR_INFO_TYPE,
+ DECLARED_ACCESSOR_DESCRIPTOR_TYPE,
+ DECLARED_ACCESSOR_INFO_TYPE,
+ EXECUTABLE_ACCESSOR_INFO_TYPE,
ACCESSOR_PAIR_TYPE,
ACCESS_CHECK_INFO_TYPE,
INTERCEPTOR_INFO_TYPE,
@@ -587,6 +694,7 @@ enum InstanceType {
OBJECT_TEMPLATE_INFO_TYPE,
SIGNATURE_INFO_TYPE,
TYPE_SWITCH_INFO_TYPE,
+ ALLOCATION_SITE_INFO_TYPE,
SCRIPT_TYPE,
CODE_CACHE_TYPE,
POLYMORPHIC_CODE_CACHE_TYPE,
@@ -633,7 +741,11 @@ enum InstanceType {
FIRST_TYPE = 0x0,
LAST_TYPE = JS_FUNCTION_TYPE,
INVALID_TYPE = FIRST_TYPE - 1,
- FIRST_NONSTRING_TYPE = MAP_TYPE,
+ FIRST_NAME_TYPE = FIRST_TYPE,
+ LAST_NAME_TYPE = SYMBOL_TYPE,
+ FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
+ LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
+ FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
// Boundaries for testing for an external array.
FIRST_EXTERNAL_ARRAY_TYPE = EXTERNAL_BYTE_ARRAY_TYPE,
LAST_EXTERNAL_ARRAY_TYPE = EXTERNAL_PIXEL_ARRAY_TYPE,
@@ -679,7 +791,7 @@ STATIC_CHECK(FOREIGN_TYPE == Internals::kForeignType);
V(DICTIONARY_PROPERTIES_SUB_TYPE) \
V(MAP_CODE_CACHE_SUB_TYPE) \
V(SCOPE_INFO_SUB_TYPE) \
- V(SYMBOL_TABLE_SUB_TYPE) \
+ V(STRING_TABLE_SUB_TYPE) \
V(DESCRIPTOR_ARRAY_SUB_TYPE) \
V(TRANSITION_ARRAY_SUB_TYPE)
@@ -737,6 +849,12 @@ template <class C> static inline bool Is(Object* obj);
#define DECLARE_VERIFIER(Name)
#endif
+#ifdef OBJECT_PRINT
+#define DECLARE_PRINTER(Name) void Name##Print(FILE* out = stdout);
+#else
+#define DECLARE_PRINTER(Name)
+#endif
+
class MaybeObject BASE_EMBEDDED {
public:
inline bool IsFailure();
@@ -754,7 +872,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() {
@@ -769,6 +889,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() {
@@ -794,8 +921,9 @@ class MaybeObject BASE_EMBEDDED {
#define HEAP_OBJECT_TYPE_LIST(V) \
V(HeapNumber) \
+ V(Name) \
+ V(UniqueName) \
V(String) \
- V(Symbol) \
V(SeqString) \
V(ExternalString) \
V(ConsString) \
@@ -803,7 +931,9 @@ class MaybeObject BASE_EMBEDDED {
V(ExternalTwoByteString) \
V(ExternalAsciiString) \
V(SeqTwoByteString) \
- V(SeqAsciiString) \
+ V(SeqOneByteString) \
+ V(InternalizedString) \
+ V(Symbol) \
\
V(ExternalArray) \
V(ExternalByteArray) \
@@ -826,6 +956,7 @@ class MaybeObject BASE_EMBEDDED {
V(TransitionArray) \
V(DeoptimizationInputData) \
V(DeoptimizationOutputData) \
+ V(DependentCode) \
V(TypeFeedbackCells) \
V(FixedArray) \
V(FixedDoubleArray) \
@@ -851,7 +982,7 @@ class MaybeObject BASE_EMBEDDED {
V(JSRegExp) \
V(HashTable) \
V(Dictionary) \
- V(SymbolTable) \
+ V(StringTable) \
V(JSFunctionResultCache) \
V(NormalizedMapCache) \
V(CompilationCacheTable) \
@@ -866,10 +997,9 @@ class MaybeObject BASE_EMBEDDED {
V(UndetectableObject) \
V(AccessCheckNeeded) \
V(JSGlobalPropertyCell) \
+ V(ObjectHashTable) \
-class JSReceiver;
-
// Object is the abstract superclass for all classes in the
// object hierarchy.
// Object does not use any virtual functions to avoid the
@@ -887,6 +1017,8 @@ class Object : public MaybeObject {
#undef IS_TYPE_FUNCTION_DECL
inline bool IsFixedArrayBase();
+ inline bool IsExternal();
+ inline bool IsAccessorInfo();
// Returns true if this object is an instance of the specified
// function template.
@@ -923,7 +1055,7 @@ class Object : public MaybeObject {
inline bool HasSpecificClassOf(String* name);
MUST_USE_RESULT MaybeObject* ToObject(); // ECMA-262 9.9.
- Object* ToBoolean(); // ECMA-262 9.2.
+ bool BooleanValue(); // ECMA-262 9.2.
// Convert to a JSObject if needed.
// native_context is used when creating wrapper object.
@@ -933,27 +1065,28 @@ class Object : public MaybeObject {
// Failure is returned otherwise.
MUST_USE_RESULT inline MaybeObject* ToSmi();
- void Lookup(String* name, LookupResult* result);
+ void Lookup(Name* name, LookupResult* result);
// Property access.
- MUST_USE_RESULT inline MaybeObject* GetProperty(String* key);
+ MUST_USE_RESULT inline MaybeObject* GetProperty(Name* key);
MUST_USE_RESULT inline MaybeObject* GetProperty(
- String* key,
+ Name* key,
PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetPropertyWithReceiver(
Object* receiver,
- String* key,
+ Name* key,
PropertyAttributes* attributes);
+ static Handle<Object> GetProperty(Handle<Object> object, Handle<Name> key);
static Handle<Object> GetProperty(Handle<Object> object,
Handle<Object> receiver,
LookupResult* result,
- Handle<String> key,
+ Handle<Name> key,
PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetProperty(Object* receiver,
LookupResult* result,
- String* key,
+ Name* key,
PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetPropertyWithDefinedGetter(Object* receiver,
@@ -967,7 +1100,10 @@ class Object : public MaybeObject {
uint32_t index);
// Return the object's prototype (might be Heap::null_value()).
- Object* GetPrototype();
+ Object* GetPrototype(Isolate* isolate);
+
+ // Return the prototype, or the method holder for a value-like object.
+ Object* GetDelegate(Isolate* isolate);
// Returns the permanent hash code associated with this object depending on
// the actual object type. Might return a failure in case no hash was
@@ -1104,7 +1240,9 @@ class Failure: public MaybeObject {
static inline Failure* RetryAfterGC(); // NEW_SPACE
static inline Failure* Exception();
static inline Failure* InternalError();
- static inline Failure* OutOfMemoryException();
+ // TODO(jkummerow): The value is temporary instrumentation. Remove it
+ // when it has served its purpose.
+ static inline Failure* OutOfMemoryException(intptr_t value);
// Casting.
static inline Failure* cast(MaybeObject* object);
@@ -1327,7 +1465,8 @@ class HeapNumber: public HeapObject {
static inline HeapNumber* cast(Object* obj);
// Dispatched behavior.
- Object* HeapNumberToBoolean();
+ bool HeapNumberBooleanValue();
+
inline void HeapNumberPrint() {
HeapNumberPrint(stdout);
}
@@ -1415,20 +1554,20 @@ class JSReceiver: public HeapObject {
static inline JSReceiver* cast(Object* obj);
static Handle<Object> SetProperty(Handle<JSReceiver> object,
- Handle<String> key,
+ Handle<Name> key,
Handle<Object> value,
PropertyAttributes attributes,
StrictModeFlag strict_mode);
// Can cause GC.
MUST_USE_RESULT MaybeObject* SetProperty(
- String* key,
+ Name* key,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
StoreFromKeyed store_from_keyed = MAY_BE_STORE_FROM_KEYED);
MUST_USE_RESULT MaybeObject* SetProperty(
LookupResult* result,
- String* key,
+ Name* key,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
@@ -1436,7 +1575,7 @@ class JSReceiver: public HeapObject {
MUST_USE_RESULT MaybeObject* SetPropertyWithDefinedSetter(JSReceiver* setter,
Object* value);
- MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode);
+ MUST_USE_RESULT MaybeObject* DeleteProperty(Name* name, DeleteMode mode);
MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode);
// Set the index'th array element.
@@ -1457,15 +1596,19 @@ class JSReceiver: public HeapObject {
// function that was used to instantiate the object).
String* constructor_name();
- inline PropertyAttributes GetPropertyAttribute(String* name);
+ inline PropertyAttributes GetPropertyAttribute(Name* name);
PropertyAttributes GetPropertyAttributeWithReceiver(JSReceiver* receiver,
- String* name);
- PropertyAttributes GetLocalPropertyAttribute(String* name);
+ Name* name);
+ PropertyAttributes GetLocalPropertyAttribute(Name* 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 HasProperty(Name* name);
+ inline bool HasLocalProperty(Name* 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();
@@ -1483,17 +1626,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 Lookup(String* name, LookupResult* result);
+ void LocalLookup(Name* name, LookupResult* result,
+ bool search_hidden_prototypes = false);
+ void Lookup(Name* name, LookupResult* result);
protected:
Smi* GenerateIdentityHash();
private:
- PropertyAttributes GetPropertyAttribute(JSReceiver* receiver,
- LookupResult* result,
- String* name,
- bool continue_search);
+ PropertyAttributes GetPropertyAttributeForResult(JSReceiver* receiver,
+ LookupResult* result,
+ Name* name,
+ bool continue_search);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
};
@@ -1510,7 +1654,7 @@ class JSObject: public JSReceiver {
DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties.
inline void initialize_properties();
inline bool HasFastProperties();
- inline StringDictionary* property_dictionary(); // Gets slow properties.
+ inline NameDictionary* property_dictionary(); // Gets slow properties.
// [elements]: The elements (properties with names that are integers).
//
@@ -1542,6 +1686,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();
@@ -1582,34 +1728,34 @@ class JSObject: public JSReceiver {
MUST_USE_RESULT MaybeObject* GetPropertyWithCallback(Object* receiver,
Object* structure,
- String* name);
+ Name* name);
// Can cause GC.
MUST_USE_RESULT MaybeObject* SetPropertyForResult(LookupResult* result,
- String* key,
+ Name* key,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
StoreFromKeyed store_mode);
MUST_USE_RESULT MaybeObject* SetPropertyWithFailedAccessCheck(
LookupResult* result,
- String* name,
+ Name* name,
Object* value,
bool check_prototype,
StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* SetPropertyWithCallback(
Object* structure,
- String* name,
+ Name* name,
Object* value,
JSObject* holder,
StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* SetPropertyWithInterceptor(
- String* name,
+ Name* name,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* SetPropertyPostInterceptor(
- String* name,
+ Name* name,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
@@ -1617,14 +1763,14 @@ class JSObject: public JSReceiver {
static Handle<Object> SetLocalPropertyIgnoreAttributes(
Handle<JSObject> object,
- Handle<String> key,
+ Handle<Name> key,
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);
+ Handle<Name> key);
inline int LastAddedFieldIndex();
@@ -1635,7 +1781,7 @@ class JSObject: public JSReceiver {
// Can cause GC.
MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
- String* key,
+ Name* key,
Object* value,
PropertyAttributes attributes);
@@ -1650,16 +1796,16 @@ class JSObject: public JSReceiver {
// Sets the property value in a normalized object given (key, value, details).
// Handles the special representation of JS global objects.
static Handle<Object> SetNormalizedProperty(Handle<JSObject> object,
- Handle<String> key,
+ Handle<Name> key,
Handle<Object> value,
PropertyDetails details);
- MUST_USE_RESULT MaybeObject* SetNormalizedProperty(String* name,
+ MUST_USE_RESULT MaybeObject* SetNormalizedProperty(Name* name,
Object* value,
PropertyDetails details);
// Deletes the named property in a normalized object.
- MUST_USE_RESULT MaybeObject* DeleteNormalizedProperty(String* name,
+ MUST_USE_RESULT MaybeObject* DeleteNormalizedProperty(Name* name,
DeleteMode mode);
MUST_USE_RESULT MaybeObject* OptimizeAsPrototype();
@@ -1670,23 +1816,27 @@ class JSObject: public JSReceiver {
// Used from JSReceiver.
PropertyAttributes GetPropertyAttributePostInterceptor(JSObject* receiver,
- String* name,
+ Name* name,
bool continue_search);
PropertyAttributes GetPropertyAttributeWithInterceptor(JSObject* receiver,
- String* name,
+ Name* name,
bool continue_search);
PropertyAttributes GetPropertyAttributeWithFailedAccessCheck(
Object* receiver,
LookupResult* result,
- String* name,
+ Name* name,
bool continue_search);
+ PropertyAttributes GetElementAttributeWithReceiver(JSReceiver* receiver,
+ uint32_t index,
+ bool continue_search);
static void DefineAccessor(Handle<JSObject> object,
- Handle<String> name,
+ Handle<Name> name,
Handle<Object> getter,
Handle<Object> setter,
PropertyAttributes attributes);
- MUST_USE_RESULT MaybeObject* DefineAccessor(String* name,
+ // Can cause GC.
+ MUST_USE_RESULT MaybeObject* DefineAccessor(Name* name,
Object* getter,
Object* setter,
PropertyAttributes attributes);
@@ -1694,11 +1844,11 @@ class JSObject: public JSReceiver {
// Returns a JavaScript null if this was not possible and we have to use the
// slow case. Note that we can fail due to allocations, too.
MUST_USE_RESULT MaybeObject* DefineFastAccessor(
- String* name,
+ Name* name,
AccessorComponent component,
Object* accessor,
PropertyAttributes attributes);
- Object* LookupAccessor(String* name, AccessorComponent component);
+ Object* LookupAccessor(Name* name, AccessorComponent component);
MUST_USE_RESULT MaybeObject* DefineAccessor(AccessorInfo* info);
@@ -1706,19 +1856,19 @@ class JSObject: public JSReceiver {
MUST_USE_RESULT MaybeObject* GetPropertyWithFailedAccessCheck(
Object* receiver,
LookupResult* result,
- String* name,
+ Name* name,
PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetPropertyWithInterceptor(
Object* receiver,
- String* name,
+ Name* name,
PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetPropertyPostInterceptor(
Object* receiver,
- String* name,
+ Name* name,
PropertyAttributes* attributes);
MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor(
Object* receiver,
- String* name,
+ Name* name,
PropertyAttributes* attributes);
// Returns true if this is an instance of an api function and has
@@ -1733,7 +1883,7 @@ class JSObject: public JSReceiver {
//
// Hidden properties are not local properties of the object itself.
// Instead they are stored in an auxiliary structure kept as a local
- // property with a special name Heap::hidden_symbol(). But if the
+ // property with a special name Heap::hidden_string(). But if the
// receiver is a JSGlobalProxy then the auxiliary object is a property
// of its prototype, and if it's a detached proxy, then you can't have
// hidden properties.
@@ -1741,18 +1891,18 @@ class JSObject: public JSReceiver {
// Sets a hidden property on this object. Returns this object if successful,
// undefined if called on a detached proxy.
static Handle<Object> SetHiddenProperty(Handle<JSObject> obj,
- Handle<String> key,
+ Handle<Name> key,
Handle<Object> value);
// Returns a failure if a GC is required.
- MUST_USE_RESULT MaybeObject* SetHiddenProperty(String* key, Object* value);
+ MUST_USE_RESULT MaybeObject* SetHiddenProperty(Name* key, Object* value);
// Gets the value of a hidden property with the given key. Returns undefined
// if the property doesn't exist (or if called on a detached proxy),
// otherwise returns the value set for the key.
- Object* GetHiddenProperty(String* key);
+ Object* GetHiddenProperty(Name* key);
// Deletes a hidden property. Deleting a non-existing property is
// considered successful.
- void DeleteHiddenProperty(String* key);
- // Returns true if the object has a property with the hidden symbol as name.
+ void DeleteHiddenProperty(Name* key);
+ // Returns true if the object has a property with the hidden string as name.
bool HasHiddenProperties();
static int GetIdentityHash(Handle<JSObject> obj);
@@ -1760,8 +1910,9 @@ class JSObject: public JSReceiver {
MUST_USE_RESULT MaybeObject* SetIdentityHash(Smi* hash, CreationFlag flag);
static Handle<Object> DeleteProperty(Handle<JSObject> obj,
- Handle<String> name);
- MUST_USE_RESULT MaybeObject* DeleteProperty(String* name, DeleteMode mode);
+ Handle<Name> name);
+ // Can cause GC.
+ MUST_USE_RESULT MaybeObject* DeleteProperty(Name* name, DeleteMode mode);
static Handle<Object> DeleteElement(Handle<JSObject> obj, uint32_t index);
MUST_USE_RESULT MaybeObject* DeleteElement(uint32_t index, DeleteMode mode);
@@ -1799,36 +1950,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,
-
- // Element with given index is character in string.
- STRING_CHARACTER_ELEMENT,
-
- // Element with given index is stored in fast backing store.
- FAST_ELEMENT,
+ PropertyType GetLocalPropertyType(Name* name);
+ PropertyType GetLocalElementType(uint32_t index);
- // 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(Name* name);
+ AccessorPair* GetLocalElementAccessorPair(uint32_t index);
MUST_USE_RESULT MaybeObject* SetFastElement(uint32_t index,
Object* value,
@@ -1855,7 +1988,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,
@@ -1900,9 +2033,9 @@ class JSObject: public JSReceiver {
inline bool HasIndexedInterceptor();
// Support functions for v8 api (needed for correct interceptor behavior).
- bool HasRealNamedProperty(String* key);
+ bool HasRealNamedProperty(Name* key);
bool HasRealElementProperty(uint32_t index);
- bool HasRealNamedCallbackProperty(String* key);
+ bool HasRealNamedCallbackProperty(Name* key);
// Get the header size for a JSObject. Used to compute the index of
// internal fields as well as the number of internal fields.
@@ -1915,12 +2048,12 @@ class JSObject: public JSReceiver {
inline void SetInternalField(int index, Smi* value);
// The following lookup functions skip interceptors.
- void LocalLookupRealNamedProperty(String* name, LookupResult* result);
- void LookupRealNamedProperty(String* name, LookupResult* result);
- void LookupRealNamedPropertyInPrototypes(String* name, LookupResult* result);
+ void LocalLookupRealNamedProperty(Name* name, LookupResult* result);
+ void LookupRealNamedProperty(Name* name, LookupResult* result);
+ void LookupRealNamedPropertyInPrototypes(Name* name, LookupResult* result);
MUST_USE_RESULT MaybeObject* SetElementWithCallbackSetterInPrototypes(
uint32_t index, Object* value, bool* found, StrictModeFlag strict_mode);
- void LookupCallbackProperty(String* name, LookupResult* result);
+ void LookupCallbackProperty(Name* name, LookupResult* result);
// Returns the number of properties on this object filtering out properties
// with the specified attributes (ignoring interceptors).
@@ -1947,7 +2080,7 @@ class JSObject: public JSReceiver {
// Add a property to a fast-case object using a map transition to
// new_map.
MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(Map* new_map,
- String* name,
+ Name* name,
Object* value,
int field_index);
@@ -1958,12 +2091,12 @@ class JSObject: public JSReceiver {
// This avoids the creation of many maps with the same constant
// function, all orphaned.
MUST_USE_RESULT MaybeObject* AddConstantFunctionProperty(
- String* name,
+ Name* name,
JSFunction* function,
PropertyAttributes attributes);
MUST_USE_RESULT MaybeObject* ReplaceSlowProperty(
- String* name,
+ Name* name,
Object* value,
PropertyAttributes attributes);
@@ -1981,36 +2114,38 @@ class JSObject: public JSReceiver {
ElementsKind to_kind);
MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind to_kind);
+ MUST_USE_RESULT MaybeObject* UpdateAllocationSiteInfo(
+ ElementsKind to_kind);
// Replaces an existing transition with a transition to a map with a FIELD.
MUST_USE_RESULT MaybeObject* ConvertTransitionToMapTransition(
int transition_index,
- String* name,
+ Name* name,
Object* new_value,
PropertyAttributes attributes);
// Converts a descriptor of any other type to a real field, backed by the
// properties array.
MUST_USE_RESULT MaybeObject* ConvertDescriptorToField(
- String* name,
+ Name* name,
Object* new_value,
PropertyAttributes attributes);
// Add a property to a fast-case object.
MUST_USE_RESULT MaybeObject* AddFastProperty(
- String* name,
+ Name* name,
Object* value,
PropertyAttributes attributes,
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
// Add a property to a slow-case object.
- MUST_USE_RESULT MaybeObject* AddSlowProperty(String* name,
+ MUST_USE_RESULT MaybeObject* AddSlowProperty(Name* name,
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,
+ Name* name,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
@@ -2037,10 +2172,10 @@ class JSObject: public JSReceiver {
MUST_USE_RESULT MaybeObject* NormalizeElements();
static void UpdateMapCodeCache(Handle<JSObject> object,
- Handle<String> name,
+ Handle<Name> name,
Handle<Code> code);
- MUST_USE_RESULT MaybeObject* UpdateMapCodeCache(String* name, Code* code);
+ MUST_USE_RESULT MaybeObject* UpdateMapCodeCache(Name* name, Code* code);
// Transform slow named properties to fast variants.
// Returns failure if allocation failed.
@@ -2084,12 +2219,7 @@ class JSObject: public JSReceiver {
// Dispatched behavior.
void JSObjectShortPrint(StringStream* accumulator);
-#ifdef OBJECT_PRINT
- inline void JSObjectPrint() {
- JSObjectPrint(stdout);
- }
- void JSObjectPrint(FILE* out);
-#endif
+ DECLARE_PRINTER(JSObject)
DECLARE_VERIFIER(JSObject)
#ifdef OBJECT_PRINT
inline void PrintProperties() {
@@ -2179,6 +2309,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<Name> name,
+ Handle<Object> old_value);
+
+ // Deliver change records to observers. May cause GC.
+ static void DeliverChangeRecords(Isolate* isolate);
+
private:
friend class DictionaryElementsAccessor;
@@ -2186,6 +2325,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,
@@ -2212,15 +2359,15 @@ class JSObject: public JSReceiver {
// read-only, reject and set '*done' to true. Otherwise, set '*done' to
// false. Can cause GC and can return a failure result with '*done==true'.
MUST_USE_RESULT MaybeObject* SetPropertyViaPrototypes(
- String* name,
+ Name* name,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
bool* done);
- MUST_USE_RESULT MaybeObject* DeletePropertyPostInterceptor(String* name,
+ MUST_USE_RESULT MaybeObject* DeletePropertyPostInterceptor(Name* name,
DeleteMode mode);
- MUST_USE_RESULT MaybeObject* DeletePropertyWithInterceptor(String* name);
+ MUST_USE_RESULT MaybeObject* DeletePropertyWithInterceptor(Name* name);
MUST_USE_RESULT MaybeObject* DeleteElementWithInterceptor(uint32_t index);
@@ -2238,13 +2385,13 @@ class JSObject: public JSReceiver {
// Gets the current elements capacity and the number of used elements.
void GetElementsCapacityAndUsage(int* capacity, int* used);
- bool CanSetCallback(String* name);
+ bool CanSetCallback(Name* name);
MUST_USE_RESULT MaybeObject* SetElementCallback(
uint32_t index,
Object* structure,
PropertyAttributes attributes);
MUST_USE_RESULT MaybeObject* SetPropertyCallback(
- String* name,
+ Name* name,
Object* structure,
PropertyAttributes attributes);
MUST_USE_RESULT MaybeObject* DefineElementAccessor(
@@ -2252,9 +2399,9 @@ class JSObject: public JSReceiver {
Object* getter,
Object* setter,
PropertyAttributes attributes);
- MUST_USE_RESULT MaybeObject* CreateAccessorPairFor(String* name);
+ MUST_USE_RESULT MaybeObject* CreateAccessorPairFor(Name* name);
MUST_USE_RESULT MaybeObject* DefinePropertyAccessor(
- String* name,
+ Name* name,
Object* getter,
Object* setter,
PropertyAttributes attributes);
@@ -2330,12 +2477,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);
@@ -2366,12 +2513,7 @@ class FixedArray: public FixedArrayBase {
static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
// Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void FixedArrayPrint() {
- FixedArrayPrint(stdout);
- }
- void FixedArrayPrint(FILE* out);
-#endif
+ DECLARE_PRINTER(FixedArray)
DECLARE_VERIFIER(FixedArray)
#ifdef DEBUG
// Checks if two FixedArrays have identical contents.
@@ -2410,6 +2552,8 @@ class FixedArray: public FixedArrayBase {
Object* value);
private:
+ STATIC_CHECK(kHeaderSize == Internals::kFixedArrayHeaderSize);
+
DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
};
@@ -2435,6 +2579,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); }
@@ -2453,12 +2600,7 @@ class FixedDoubleArray: public FixedArrayBase {
static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
// Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void FixedDoubleArrayPrint() {
- FixedDoubleArrayPrint(stdout);
- }
- void FixedDoubleArrayPrint(FILE* out);
-#endif
+ DECLARE_PRINTER(FixedDoubleArray)
DECLARE_VERIFIER(FixedDoubleArray)
private:
@@ -2560,10 +2702,12 @@ class DescriptorArray: public FixedArray {
Object* new_index_cache);
// Accessors for fetching instance descriptor at descriptor number.
- inline String* GetKey(int descriptor_number);
+ inline Name* GetKey(int descriptor_number);
inline Object** GetKeySlot(int descriptor_number);
inline Object* GetValue(int descriptor_number);
inline Object** GetValueSlot(int descriptor_number);
+ inline Object** GetDescriptorStartSlot(int descriptor_number);
+ inline Object** GetDescriptorEndSlot(int descriptor_number);
inline PropertyDetails GetDetails(int descriptor_number);
inline PropertyType GetType(int descriptor_number);
inline int GetFieldIndex(int descriptor_number);
@@ -2571,7 +2715,7 @@ class DescriptorArray: public FixedArray {
inline Object* GetCallbacksObject(int descriptor_number);
inline AccessorDescriptor* GetCallbacks(int descriptor_number);
- inline String* GetSortedKey(int descriptor_number);
+ inline Name* GetSortedKey(int descriptor_number);
inline int GetSortedKeyIndex(int descriptor_number);
inline void SetSortedKey(int pointer, int descriptor_number);
@@ -2601,11 +2745,11 @@ class DescriptorArray: public FixedArray {
void Sort();
// Search the instance descriptors for given name.
- INLINE(int Search(String* name, int number_of_own_descriptors));
+ INLINE(int Search(Name* name, int number_of_own_descriptors));
// As the above, but uses DescriptorLookupCache and updates it when
// necessary.
- INLINE(int SearchWithCache(String* name, Map* map));
+ INLINE(int SearchWithCache(Name* name, Map* map));
// Allocates a DescriptorArray, but returns the singleton
// empty descriptor array object if number_of_descriptors is 0.
@@ -2714,11 +2858,11 @@ class DescriptorArray: public FixedArray {
enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
template<SearchMode search_mode, typename T>
-inline int LinearSearch(T* array, String* name, int len, int valid_entries);
+inline int LinearSearch(T* array, Name* name, int len, int valid_entries);
template<SearchMode search_mode, typename T>
-inline int Search(T* array, String* name, int valid_entries = 0);
+inline int Search(T* array, Name* name, int valid_entries = 0);
// HashTable is a subclass of FixedArray that implements a hash table
@@ -2743,7 +2887,7 @@ inline int Search(T* array, String* name, int valid_entries = 0);
// // Returns the hash value for object.
// static uint32_t HashForObject(Key key, Object* object);
// // Convert key to an object.
-// static inline Object* AsObject(Key key);
+// static inline Object* AsObject(Heap* heap, Key key);
// // The prefix size indicates number of elements in the beginning
// // of the backing storage.
// static const int kPrefixSize = ..;
@@ -2829,6 +2973,7 @@ class HashTable: public FixedArray {
// Returns a new HashTable object. Might return Failure.
MUST_USE_RESULT static MaybeObject* Allocate(
+ Heap* heap,
int at_least_space_for,
MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
PretenureFlag pretenure = NOT_TENURED);
@@ -2951,13 +3096,13 @@ class HashTableKey {
virtual uint32_t HashForObject(Object* key) = 0;
// Returns the key object for storing into the hash table.
// If allocations fails a failure object is returned.
- MUST_USE_RESULT virtual MaybeObject* AsObject() = 0;
+ MUST_USE_RESULT virtual MaybeObject* AsObject(Heap* heap) = 0;
// Required.
virtual ~HashTableKey() {}
};
-class SymbolTableShape : public BaseShape<HashTableKey*> {
+class StringTableShape : public BaseShape<HashTableKey*> {
public:
static inline bool IsMatch(HashTableKey* key, Object* value) {
return key->IsMatch(value);
@@ -2968,53 +3113,58 @@ class SymbolTableShape : public BaseShape<HashTableKey*> {
static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
return key->HashForObject(object);
}
- MUST_USE_RESULT static inline MaybeObject* AsObject(HashTableKey* key) {
- return key->AsObject();
+ MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
+ HashTableKey* key) {
+ return key->AsObject(heap);
}
static const int kPrefixSize = 0;
static const int kEntrySize = 1;
};
-class SeqAsciiString;
+class SeqOneByteString;
-// SymbolTable.
+// StringTable.
//
// No special elements in the prefix and the element size is 1
-// because only the symbol itself (the key) needs to be stored.
-class SymbolTable: public HashTable<SymbolTableShape, HashTableKey*> {
+// because only the string itself (the key) needs to be stored.
+class StringTable: public HashTable<StringTableShape, HashTableKey*> {
public:
- // Find symbol in the symbol table. If it is not there yet, it is
- // added. The return value is the symbol table which might have
- // been enlarged. If the return value is not a failure, the symbol
- // pointer *s is set to the symbol found.
- MUST_USE_RESULT MaybeObject* LookupSymbol(Vector<const char> str, Object** s);
- MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(Vector<const char> str,
- Object** s);
- MUST_USE_RESULT MaybeObject* LookupSubStringAsciiSymbol(
- Handle<SeqAsciiString> str,
+ // Find string in the string table. If it is not there yet, it is
+ // added. The return value is the string table which might have
+ // been enlarged. If the return value is not a failure, the string
+ // pointer *s is set to the string found.
+ MUST_USE_RESULT MaybeObject* LookupUtf8String(
+ Vector<const char> str,
+ Object** s);
+ MUST_USE_RESULT MaybeObject* LookupOneByteString(
+ Vector<const uint8_t> str,
+ Object** s);
+ MUST_USE_RESULT MaybeObject* LookupSubStringOneByteString(
+ Handle<SeqOneByteString> str,
int from,
int length,
Object** s);
- MUST_USE_RESULT MaybeObject* LookupTwoByteSymbol(Vector<const uc16> str,
- Object** s);
+ MUST_USE_RESULT MaybeObject* LookupTwoByteString(
+ Vector<const uc16> str,
+ Object** s);
MUST_USE_RESULT MaybeObject* LookupString(String* key, Object** s);
- // Looks up a symbol that is equal to the given string and returns
- // true if it is found, assigning the symbol to the given output
+ // Looks up a string that is equal to the given string and returns
+ // true if it is found, assigning the string to the given output
// parameter.
- bool LookupSymbolIfExists(String* str, String** symbol);
- bool LookupTwoCharsSymbolIfExists(uint32_t c1, uint32_t c2, String** symbol);
+ bool LookupStringIfExists(String* str, String** result);
+ bool LookupTwoCharsStringIfExists(uint16_t c1, uint16_t c2, String** result);
// Casting.
- static inline SymbolTable* cast(Object* obj);
+ static inline StringTable* cast(Object* obj);
private:
MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s);
template <bool seq_ascii> friend class JsonParser;
- DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable);
};
@@ -3031,8 +3181,9 @@ class MapCacheShape : public BaseShape<HashTableKey*> {
return key->HashForObject(object);
}
- MUST_USE_RESULT static inline MaybeObject* AsObject(HashTableKey* key) {
- return key->AsObject();
+ MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
+ HashTableKey* key) {
+ return key->AsObject(heap);
}
static const int kPrefixSize = 0;
@@ -3042,11 +3193,11 @@ class MapCacheShape : public BaseShape<HashTableKey*> {
// MapCache.
//
-// Maps keys that are a fixed array of symbols to a map.
+// Maps keys that are a fixed array of unique names to a map.
// Used for canonicalize maps for object literals.
class MapCache: public HashTable<MapCacheShape, HashTableKey*> {
public:
- // Find cached value for a string key, otherwise return null.
+ // Find cached value for a name key, otherwise return null.
Object* Lookup(FixedArray* key);
MUST_USE_RESULT MaybeObject* Put(FixedArray* key, Map* value);
static inline MapCache* cast(Object* obj);
@@ -3120,7 +3271,8 @@ class Dictionary: public HashTable<Shape, Key> {
}
// Returns a new array for dictionary usage. Might return Failure.
- MUST_USE_RESULT static MaybeObject* Allocate(int at_least_space_for);
+ MUST_USE_RESULT static MaybeObject* Allocate(Heap* heap,
+ int at_least_space_for);
// Ensure enough space for n additional elements.
MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key);
@@ -3165,29 +3317,30 @@ class Dictionary: public HashTable<Shape, Key> {
};
-class StringDictionaryShape : public BaseShape<String*> {
+class NameDictionaryShape : public BaseShape<Name*> {
public:
- static inline bool IsMatch(String* key, Object* other);
- static inline uint32_t Hash(String* key);
- static inline uint32_t HashForObject(String* key, Object* object);
- MUST_USE_RESULT static inline MaybeObject* AsObject(String* key);
+ static inline bool IsMatch(Name* key, Object* other);
+ static inline uint32_t Hash(Name* key);
+ static inline uint32_t HashForObject(Name* key, Object* object);
+ MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
+ Name* key);
static const int kPrefixSize = 2;
static const int kEntrySize = 3;
static const bool kIsEnumerable = true;
};
-class StringDictionary: public Dictionary<StringDictionaryShape, String*> {
+class NameDictionary: public Dictionary<NameDictionaryShape, Name*> {
public:
- static inline StringDictionary* cast(Object* obj) {
+ static inline NameDictionary* cast(Object* obj) {
ASSERT(obj->IsDictionary());
- return reinterpret_cast<StringDictionary*>(obj);
+ return reinterpret_cast<NameDictionary*>(obj);
}
// Copies enumerable keys to preallocated fixed array.
FixedArray* CopyEnumKeysTo(FixedArray* storage);
static void DoGenerateNewEnumerationIndices(
- Handle<StringDictionary> dictionary);
+ Handle<NameDictionary> dictionary);
// For transforming properties of a JSObject.
MUST_USE_RESULT MaybeObject* TransformPropertiesToFastFor(
@@ -3196,14 +3349,15 @@ class StringDictionary: public Dictionary<StringDictionaryShape, String*> {
// Find entry for key, otherwise return kNotFound. Optimized version of
// HashTable::FindEntry.
- int FindEntry(String* key);
+ int FindEntry(Name* key);
};
class NumberDictionaryShape : public BaseShape<uint32_t> {
public:
static inline bool IsMatch(uint32_t key, Object* other);
- MUST_USE_RESULT static inline MaybeObject* AsObject(uint32_t key);
+ MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
+ uint32_t key);
static const int kEntrySize = 3;
static const bool kIsEnumerable = false;
};
@@ -3307,7 +3461,8 @@ class ObjectHashTableShape : public BaseShape<Object*> {
static inline bool IsMatch(Object* key, Object* other);
static inline uint32_t Hash(Object* key);
static inline uint32_t HashForObject(Object* key, Object* object);
- MUST_USE_RESULT static inline MaybeObject* AsObject(Object* key);
+ MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
+ Object* key);
static const int kPrefixSize = 0;
static const int kEntrySize = entrysize;
};
@@ -3475,13 +3630,13 @@ class ScopeInfo : public FixedArray {
// Lookup support for serialized scope info. Returns the
// the stack slot index for a given slot name if the slot is
- // present; otherwise returns a value < 0. The name must be a symbol
- // (canonicalized).
+ // present; otherwise returns a value < 0. The name must be an internalized
+ // string.
int StackSlotIndex(String* name);
// Lookup support for serialized scope info. Returns the
// context slot index for a given slot name if the slot is present; otherwise
- // returns a value < 0. The name must be a symbol (canonicalized).
+ // returns a value < 0. The name must be an internalized string.
// If the slot is present and mode != NULL, sets *mode to the corresponding
// mode for that variable.
int ContextSlotIndex(String* name,
@@ -3490,19 +3645,26 @@ class ScopeInfo : public FixedArray {
// Lookup support for serialized scope info. Returns the
// parameter index for a given parameter name if the parameter is present;
- // otherwise returns a value < 0. The name must be a symbol (canonicalized).
+ // otherwise returns a value < 0. The name must be an internalized string.
int ParameterIndex(String* name);
// Lookup support for serialized scope info. Returns the function context
// slot index if the function name is present and context-allocated (named
// function expressions, only), otherwise returns a value < 0. The name
- // must be a symbol (canonicalized).
+ // must be an internalized string.
int FunctionContextSlotIndex(String* name, VariableMode* mode);
+
+ // Copies all the context locals into an object used to materialize a scope.
+ bool CopyContextLocalsToScopeObject(Isolate* isolate,
+ Handle<Context> context,
+ Handle<JSObject> scope_object);
+
+
static Handle<ScopeInfo> Create(Scope* scope, Zone* zone);
// Serializes empty scope info.
- static ScopeInfo* Empty();
+ static ScopeInfo* Empty(Isolate* isolate);
#ifdef DEBUG
void Print();
@@ -3658,12 +3820,7 @@ class ByteArray: public FixedArrayBase {
inline int ByteArraySize() {
return SizeFor(this->length());
}
-#ifdef OBJECT_PRINT
- inline void ByteArrayPrint() {
- ByteArrayPrint(stdout);
- }
- void ByteArrayPrint(FILE* out);
-#endif
+ DECLARE_PRINTER(ByteArray)
DECLARE_VERIFIER(ByteArray)
// Layout description.
@@ -3692,12 +3849,8 @@ class FreeSpace: public HeapObject {
// Casting.
static inline FreeSpace* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void FreeSpacePrint() {
- FreeSpacePrint(stdout);
- }
- void FreeSpacePrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(FreeSpace)
DECLARE_VERIFIER(FreeSpace)
// Layout description.
@@ -3772,12 +3925,8 @@ class ExternalPixelArray: public ExternalArray {
// Casting.
static inline ExternalPixelArray* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void ExternalPixelArrayPrint() {
- ExternalPixelArrayPrint(stdout);
- }
- void ExternalPixelArrayPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(ExternalPixelArray)
DECLARE_VERIFIER(ExternalPixelArray)
private:
@@ -3799,12 +3948,8 @@ class ExternalByteArray: public ExternalArray {
// Casting.
static inline ExternalByteArray* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void ExternalByteArrayPrint() {
- ExternalByteArrayPrint(stdout);
- }
- void ExternalByteArrayPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(ExternalByteArray)
DECLARE_VERIFIER(ExternalByteArray)
private:
@@ -3826,12 +3971,8 @@ class ExternalUnsignedByteArray: public ExternalArray {
// Casting.
static inline ExternalUnsignedByteArray* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void ExternalUnsignedByteArrayPrint() {
- ExternalUnsignedByteArrayPrint(stdout);
- }
- void ExternalUnsignedByteArrayPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(ExternalUnsignedByteArray)
DECLARE_VERIFIER(ExternalUnsignedByteArray)
private:
@@ -3853,12 +3994,8 @@ class ExternalShortArray: public ExternalArray {
// Casting.
static inline ExternalShortArray* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void ExternalShortArrayPrint() {
- ExternalShortArrayPrint(stdout);
- }
- void ExternalShortArrayPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(ExternalShortArray)
DECLARE_VERIFIER(ExternalShortArray)
private:
@@ -3880,12 +4017,8 @@ class ExternalUnsignedShortArray: public ExternalArray {
// Casting.
static inline ExternalUnsignedShortArray* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void ExternalUnsignedShortArrayPrint() {
- ExternalUnsignedShortArrayPrint(stdout);
- }
- void ExternalUnsignedShortArrayPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(ExternalUnsignedShortArray)
DECLARE_VERIFIER(ExternalUnsignedShortArray)
private:
@@ -3907,12 +4040,8 @@ class ExternalIntArray: public ExternalArray {
// Casting.
static inline ExternalIntArray* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void ExternalIntArrayPrint() {
- ExternalIntArrayPrint(stdout);
- }
- void ExternalIntArrayPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(ExternalIntArray)
DECLARE_VERIFIER(ExternalIntArray)
private:
@@ -3934,12 +4063,8 @@ class ExternalUnsignedIntArray: public ExternalArray {
// Casting.
static inline ExternalUnsignedIntArray* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void ExternalUnsignedIntArrayPrint() {
- ExternalUnsignedIntArrayPrint(stdout);
- }
- void ExternalUnsignedIntArrayPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(ExternalUnsignedIntArray)
DECLARE_VERIFIER(ExternalUnsignedIntArray)
private:
@@ -3961,12 +4086,8 @@ class ExternalFloatArray: public ExternalArray {
// Casting.
static inline ExternalFloatArray* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void ExternalFloatArrayPrint() {
- ExternalFloatArrayPrint(stdout);
- }
- void ExternalFloatArrayPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(ExternalFloatArray)
DECLARE_VERIFIER(ExternalFloatArray)
private:
@@ -3988,12 +4109,8 @@ class ExternalDoubleArray: public ExternalArray {
// Casting.
static inline ExternalDoubleArray* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void ExternalDoubleArrayPrint() {
- ExternalDoubleArrayPrint(stdout);
- }
- void ExternalDoubleArrayPrint(FILE* out);
-#endif // OBJECT_PRINT
+ // Dispatched behavior.
+ DECLARE_PRINTER(ExternalDoubleArray)
DECLARE_VERIFIER(ExternalDoubleArray)
private:
@@ -4156,6 +4273,11 @@ class TypeFeedbackCells: public FixedArray {
// The object that indicates a megamorphic state.
static inline Handle<Object> MegamorphicSentinel(Isolate* isolate);
+ // The object that indicates a monomorphic state of Array with
+ // ElementsKind
+ static inline Handle<Object> MonomorphicArraySentinel(Isolate* isolate,
+ ElementsKind elements_kind);
+
// A raw version of the uninitialized sentinel that's safe to read during
// garbage collection (e.g., for patching the cache).
static inline Object* RawUninitializedSentinel(Heap* heap);
@@ -4177,17 +4299,13 @@ class Code: public HeapObject {
public:
// Opaque data type for encapsulating code flags like kind, inline
// cache state, and arguments count.
- // FLAGS_MIN_VALUE and FLAGS_MAX_VALUE are specified to ensure that
- // enumeration type has correct value range (see Issue 830 for more details).
- enum Flags {
- FLAGS_MIN_VALUE = kMinInt,
- FLAGS_MAX_VALUE = kMaxInt
- };
+ typedef uint32_t Flags;
#define CODE_KIND_LIST(V) \
V(FUNCTION) \
V(OPTIMIZED_FUNCTION) \
V(STUB) \
+ V(COMPILED_STUB) \
V(BUILTIN) \
V(LOAD_IC) \
V(KEYED_LOAD_IC) \
@@ -4216,6 +4334,8 @@ class Code: public HeapObject {
// Flags.
STATIC_ASSERT(LAST_CODE_KIND < 16);
+ static const char* Kind2String(Kind kind);
+
// Types of stubs.
enum StubType {
NORMAL,
@@ -4237,7 +4357,6 @@ class Code: public HeapObject {
#ifdef ENABLE_DISASSEMBLER
// Printing
- static const char* Kind2String(Kind kind);
static const char* ICState2String(InlineCacheState state);
static const char* StubType2String(StubType type);
static void PrintExtraICState(FILE* out, Kind kind, ExtraICState extra);
@@ -4261,9 +4380,18 @@ class Code: public HeapObject {
// [deoptimization_data]: Array containing data for deopt.
DECL_ACCESSORS(deoptimization_data, FixedArray)
- // [type_feedback_info]: Struct containing type feedback information.
- // Will contain either a TypeFeedbackInfo object, or undefined.
+ // [type_feedback_info]: Struct containing type feedback information for
+ // unoptimized code. Optimized code can temporarily store the head of
+ // the list of the dependent optimized functions during deoptimization.
+ // STUBs can use this slot to store arbitrary information as a Smi.
+ // Will contain either a TypeFeedbackInfo object, or JSFunction 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);
+ inline Object* deoptimizing_functions();
+ inline void set_deoptimizing_functions(Object* value);
// [gc_metadata]: Field used to hold GC related metadata. The contents of this
// field does not have to be traced during garbage collection since
@@ -4275,6 +4403,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();
@@ -4294,6 +4427,7 @@ class Code: public HeapObject {
// Testers for IC stub kinds.
inline bool is_inline_cache_stub();
+ inline bool is_debug_break();
inline bool is_load_stub() { return kind() == LOAD_IC; }
inline bool is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; }
inline bool is_store_stub() { return kind() == STORE_IC; }
@@ -4360,6 +4494,9 @@ class Code: public HeapObject {
inline unsigned stack_check_table_offset();
inline void set_stack_check_table_offset(unsigned offset);
+ inline bool stack_check_patched_for_osr();
+ inline void set_stack_check_patched_for_osr(bool value);
+
// [check type]: For kind CALL_IC, tells how to check if the
// receiver is valid for the given call.
inline CheckType check_type();
@@ -4369,21 +4506,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);
@@ -4393,6 +4515,12 @@ class Code: public HeapObject {
inline bool has_function_cache();
inline void set_has_function_cache(bool flag);
+
+ // [marked_for_deoptimization]: For kind OPTIMIZED_FUNCTION tells whether
+ // the code is going to be deoptimized because of dead embedded maps.
+ inline bool marked_for_deoptimization();
+ inline void set_marked_for_deoptimization(bool flag);
+
bool allowed_in_shared_map_code_cache();
// Get the safepoint entry for the given pc.
@@ -4404,26 +4532,29 @@ class Code: public HeapObject {
// Find the first map in an IC stub.
Map* FindFirstMap();
+ void FindAllMaps(MapHandleList* maps);
- class ExtraICStateStrictMode: public BitField<StrictModeFlag, 0, 1> {};
- class ExtraICStateKeyedAccessGrowMode:
- public BitField<KeyedAccessGrowMode, 1, 1> {}; // NOLINT
+ // Find the first code in an IC stub.
+ Code* FindFirstCode();
+ void FindAllCode(CodeHandleList* code_list, int length);
- static const int kExtraICStateGrowModeShift = 1;
+ class ExtraICStateStrictMode: public BitField<StrictModeFlag, 0, 1> {};
+ class ExtraICStateKeyedAccessStoreMode:
+ public BitField<KeyedAccessStoreMode, 1, 4> {}; // NOLINT
static inline StrictModeFlag GetStrictMode(ExtraICState extra_ic_state) {
return ExtraICStateStrictMode::decode(extra_ic_state);
}
- static inline KeyedAccessGrowMode GetKeyedAccessGrowMode(
+ static inline KeyedAccessStoreMode GetKeyedAccessStoreMode(
ExtraICState extra_ic_state) {
- return ExtraICStateKeyedAccessGrowMode::decode(extra_ic_state);
+ return ExtraICStateKeyedAccessStoreMode::decode(extra_ic_state);
}
static inline ExtraICState ComputeExtraICState(
- KeyedAccessGrowMode grow_mode,
+ KeyedAccessStoreMode store_mode,
StrictModeFlag strict_mode) {
- return ExtraICStateKeyedAccessGrowMode::encode(grow_mode) |
+ return ExtraICStateKeyedAccessStoreMode::encode(store_mode) |
ExtraICStateStrictMode::encode(strict_mode);
}
@@ -4438,10 +4569,10 @@ class Code: public HeapObject {
static inline Flags ComputeMonomorphicFlags(
Kind kind,
- StubType type,
ExtraICState extra_ic_state = kNoExtraICState,
- InlineCacheHolderFlag holder = OWN_MAP,
- int argc = -1);
+ StubType type = NORMAL,
+ int argc = -1,
+ InlineCacheHolderFlag holder = OWN_MAP);
static inline InlineCacheState ExtractICStateFromFlags(Flags flags);
static inline StubType ExtractTypeFromFlags(Flags flags);
@@ -4511,17 +4642,35 @@ class Code: public HeapObject {
template<typename StaticVisitor>
inline void CodeIterateBody(Heap* heap);
-#ifdef OBJECT_PRINT
- inline void CodePrint() {
- CodePrint(stdout);
- }
- void CodePrint(FILE* out);
-#endif
+
+ DECLARE_PRINTER(Code)
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();
+
+ void PrintDeoptLocation(int bailout_id);
+
+#ifdef VERIFY_HEAP
+ void VerifyEmbeddedMapsDependency();
+#endif
+
// 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;
@@ -4541,8 +4690,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.
@@ -4567,8 +4718,8 @@ class Code: public HeapObject {
class TypeField: public BitField<StubType, 3, 3> {};
class CacheHolderField: public BitField<InlineCacheHolderFlag, 6, 1> {};
class KindField: public BitField<Kind, 7, 4> {};
- class ExtraICStateField: public BitField<ExtraICState, 11, 2> {};
- class IsPregeneratedField: public BitField<bool, 13, 1> {};
+ class ExtraICStateField: public BitField<ExtraICState, 11, 5> {};
+ class IsPregeneratedField: public BitField<bool, 16, 1> {};
// KindSpecificFlags1 layout (STUB and OPTIMIZED_FUNCTION)
static const int kStackSlotsFirstBit = 0;
@@ -4576,51 +4727,34 @@ 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;
static const int kHasFunctionCacheFirstBit =
kStackSlotsFirstBit + kStackSlotsBitCount;
static const int kHasFunctionCacheBitCount = 1;
+ static const int kMarkedForDeoptimizationFirstBit =
+ kStackSlotsFirstBit + kStackSlotsBitCount + 1;
+ static const int kMarkedForDeoptimizationBitCount = 1;
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);
+ STATIC_ASSERT(kMarkedForDeoptimizationFirstBit +
+ kMarkedForDeoptimizationBitCount <= 32);
class StackSlotsField: public BitField<int,
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,
kHasFunctionCacheFirstBit, kHasFunctionCacheBitCount> {}; // NOLINT
+ class MarkedForDeoptimizationField: public BitField<bool,
+ kMarkedForDeoptimizationFirstBit,
+ kMarkedForDeoptimizationBitCount> {}; // NOLINT
// KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
static const int kStubMajorKeyFirstBit = 0;
@@ -4640,20 +4774,108 @@ class Code: public HeapObject {
// KindSpecificFlags2 layout (FUNCTION)
class StackCheckTableOffsetField: public BitField<int, 0, 31> {};
+ class StackCheckPatchedForOSRField: public BitField<bool, 31, 1> {};
// Signed field cannot be encoded using the BitField class.
- static const int kArgumentsCountShift = 14;
+ static const int kArgumentsCountShift = 17;
static const int kArgumentsCountMask = ~((1 << kArgumentsCountShift) - 1);
+ static const int kArgumentsBits =
+ PlatformSmiTagging::kSmiValueSize - Code::kArgumentsCountShift + 1;
+ static const int kMaxArguments = (1 << kArgumentsBits) - 1;
// This constant should be encodable in an ARM instruction.
static const int kFlagsNotUsedInLookup =
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);
};
+// This class describes the layout of dependent codes array of a map. The
+// array is partitioned into several groups of dependent codes. Each group
+// contains codes with the same dependency on the map. The array has the
+// following layout for n dependency groups:
+//
+// +----+----+-----+----+---------+----------+-----+---------+-----------+
+// | C1 | C2 | ... | Cn | group 1 | group 2 | ... | group n | undefined |
+// +----+----+-----+----+---------+----------+-----+---------+-----------+
+//
+// The first n elements are Smis, each of them specifies the number of codes
+// in the corresponding group. The subsequent elements contain grouped code
+// objects. The suffix of the array can be filled with the undefined value if
+// the number of codes is less than the length of the array. The order of the
+// code objects within a group is not preserved.
+//
+// All code indexes used in the class are counted starting from the first
+// code object of the first group. In other words, code index 0 corresponds
+// to array index n = kCodesStartIndex.
+
+class DependentCode: public FixedArray {
+ public:
+ enum DependencyGroup {
+ // Group of code that weakly embed this map and depend on being
+ // deoptimized when the map is garbage collected.
+ kWeaklyEmbeddedGroup,
+ // Group of code that omit run-time prototype checks for prototypes
+ // described by this map. The group is deoptimized whenever an object
+ // described by this map changes shape (and transitions to a new map),
+ // possibly invalidating the assumptions embedded in the code.
+ kPrototypeCheckGroup,
+ kGroupCount = kPrototypeCheckGroup + 1
+ };
+
+ // Array for holding the index of the first code object of each group.
+ // The last element stores the total number of code objects.
+ class GroupStartIndexes {
+ public:
+ explicit GroupStartIndexes(DependentCode* entries);
+ void Recompute(DependentCode* entries);
+ int at(int i) { return start_indexes_[i]; }
+ int number_of_entries() { return start_indexes_[kGroupCount]; }
+ private:
+ int start_indexes_[kGroupCount + 1];
+ };
+
+ bool Contains(DependencyGroup group, Code* code);
+ static Handle<DependentCode> Insert(Handle<DependentCode> entries,
+ DependencyGroup group,
+ Handle<Code> value);
+ void DeoptimizeDependentCodeGroup(Isolate* isolate,
+ DependentCode::DependencyGroup group);
+
+ // The following low-level accessors should only be used by this class
+ // and the mark compact collector.
+ inline int number_of_entries(DependencyGroup group);
+ inline void set_number_of_entries(DependencyGroup group, int value);
+ inline Code* code_at(int i);
+ inline void set_code_at(int i, Code* value);
+ inline Object** code_slot_at(int i);
+ inline void clear_code_at(int i);
+ static inline DependentCode* cast(Object* object);
+
+ private:
+ // Make a room at the end of the given group by moving out the first
+ // code objects of the subsequent groups.
+ inline void ExtendGroup(DependencyGroup group);
+ static const int kCodesStartIndex = kGroupCount;
+};
+
+
// All heap objects have a Map that describes their structure.
// A Map contains information about:
// - Size information about the object
@@ -4701,6 +4923,7 @@ class Map: public HeapObject {
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
@@ -4717,7 +4940,7 @@ class Map: public HeapObject {
inline bool function_with_prototype();
// Tells whether the instance with this map should be ignored by the
- // __proto__ accessor.
+ // Object.getPrototypeOf() function and the __proto__ accessor.
inline void set_is_hidden_prototype() {
set_bit_field(bit_field() | (1 << kIsHiddenPrototype));
}
@@ -4773,6 +4996,10 @@ class Map: public HeapObject {
inline void set_elements_kind(ElementsKind elements_kind) {
ASSERT(elements_kind < kElementsKindCount);
ASSERT(kElementsKindCount <= (1 << kElementsKindBitCount));
+ ASSERT(!is_observed() ||
+ elements_kind == DICTIONARY_ELEMENTS ||
+ elements_kind == NON_STRICT_ARGUMENTS_ELEMENTS ||
+ IsExternalArrayElementsKind(elements_kind));
set_bit_field2((bit_field2() & ~kElementsKindMask) |
(elements_kind << kElementsKindShift));
ASSERT(this->elements_kind() == elements_kind);
@@ -4801,6 +5028,10 @@ class Map: public HeapObject {
return IsFastDoubleElementsKind(elements_kind());
}
+ inline bool has_fast_elements() {
+ return IsFastElementsKind(elements_kind());
+ }
+
inline bool has_non_strict_arguments_elements() {
return elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS;
}
@@ -4828,7 +5059,7 @@ class Map: public HeapObject {
Map* transitioned_map);
inline void SetTransition(int transition_index, Map* target);
inline Map* GetTransition(int transition_index);
- MUST_USE_RESULT inline MaybeObject* AddTransition(String* key,
+ MUST_USE_RESULT inline MaybeObject* AddTransition(Name* key,
Map* target,
SimpleTransitionFlag flag);
DECL_ACCESSORS(transitions, TransitionArray)
@@ -4874,6 +5105,9 @@ class Map: public HeapObject {
// [stub cache]: contains stubs compiled for this map.
DECL_ACCESSORS(code_cache, Object)
+ // [dependent code]: list of optimized codes that have this map embedded.
+ DECL_ACCESSORS(dependent_code, DependentCode)
+
// [back pointer]: points back to the parent map from which a transition
// leads to this map. The field overlaps with prototype transitions and the
// back pointer will be moved into the prototype transitions array if
@@ -4923,11 +5157,11 @@ class Map: public HeapObject {
// with the given holder if the name is found. The holder may be
// NULL when this function is used from the compiler.
inline void LookupDescriptor(JSObject* holder,
- String* name,
+ Name* name,
LookupResult* result);
inline void LookupTransition(JSObject* holder,
- String* name,
+ Name* name,
LookupResult* result);
// The size of transition arrays are limited so they do not end up in large
@@ -4965,16 +5199,18 @@ class Map: public HeapObject {
set_bit_field3(EnumLengthBits::update(bit_field3(), length));
}
-
+ inline bool CanTrackAllocationSite();
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,
+ Name* name,
TransitionFlag flag,
int descriptor_index);
MUST_USE_RESULT MaybeObject* ShareDescriptor(DescriptorArray* descriptors,
@@ -5002,7 +5238,7 @@ class Map: public HeapObject {
MUST_USE_RESULT MaybeObject* Copy();
// Returns the property index for name (only valid for FAST MODE).
- int PropertyIndexFor(String* name);
+ int PropertyIndexFor(Name* name);
// Returns the next free property index (only valid for FAST MODE).
int NextFreePropertyIndex();
@@ -5016,7 +5252,7 @@ class Map: public HeapObject {
static inline Map* cast(Object* obj);
// Locate an accessor in the instance descriptor.
- AccessorDescriptor* FindAccessor(String* name);
+ AccessorDescriptor* FindAccessor(Name* name);
// Code cache operations.
@@ -5025,9 +5261,9 @@ class Map: public HeapObject {
// Update code cache.
static void UpdateCodeCache(Handle<Map> map,
- Handle<String> name,
+ Handle<Name> name,
Handle<Code> code);
- MUST_USE_RESULT MaybeObject* UpdateCodeCache(String* name, Code* code);
+ MUST_USE_RESULT MaybeObject* UpdateCodeCache(Name* name, Code* code);
// Extend the descriptor array of the map with the list of descriptors.
// In case of duplicates, the latest descriptor is used.
@@ -5037,14 +5273,14 @@ class Map: public HeapObject {
static void EnsureDescriptorSlack(Handle<Map> map, int slack);
// Returns the found code or undefined if absent.
- Object* FindInCodeCache(String* name, Code::Flags flags);
+ Object* FindInCodeCache(Name* name, Code::Flags flags);
// Returns the non-negative index of the code object if it is in the
// cache and -1 otherwise.
int IndexInCodeCache(Object* name, Code* code);
// Removes a code object from the code cache at the given index.
- void RemoveFromCodeCache(String* name, Code* code, int index);
+ void RemoveFromCodeCache(Name* name, Code* code, int index);
// Set all map transitions from this map to dead maps to null. Also clear
// back pointers in transition targets so that we do not process this map
@@ -5081,17 +5317,29 @@ class Map: public HeapObject {
void ZapPrototypeTransitions();
void ZapTransitions();
- // Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void MapPrint() {
- MapPrint(stdout);
+ bool CanTransition() {
+ // Only JSObject and subtypes have map transitions and back pointers.
+ STATIC_ASSERT(LAST_TYPE == LAST_JS_OBJECT_TYPE);
+ return instance_type() >= FIRST_JS_OBJECT_TYPE;
}
- void MapPrint(FILE* out);
-#endif
+
+ // Fires when the layout of an object with a leaf map changes.
+ // This includes adding transitions to the leaf map or changing
+ // the descriptor array.
+ inline void NotifyLeafMapLayoutChange();
+
+ inline bool CanOmitPrototypeChecks();
+
+ inline void AddDependentCode(DependentCode::DependencyGroup group,
+ Handle<Code> code);
+
+ // Dispatched behavior.
+ DECLARE_PRINTER(Map)
DECLARE_VERIFIER(Map)
#ifdef VERIFY_HEAP
void SharedMapVerify();
+ void VerifyOmittedPrototypeChecks();
#endif
inline int visitor_id();
@@ -5133,9 +5381,9 @@ class Map: public HeapObject {
kConstructorOffset + kPointerSize;
static const int kDescriptorsOffset =
kTransitionsOrBackPointerOffset + kPointerSize;
- static const int kCodeCacheOffset =
- kDescriptorsOffset + kPointerSize;
- static const int kBitField3Offset = kCodeCacheOffset + kPointerSize;
+ static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize;
+ static const int kDependentCodeOffset = kCodeCacheOffset + kPointerSize;
+ static const int kBitField3Offset = kDependentCodeOffset + kPointerSize;
static const int kSize = kBitField3Offset + kPointerSize;
// Layout of pointer fields. Heap iteration code relies on them
@@ -5288,12 +5536,8 @@ class Script: public Struct {
// resource is accessible. Otherwise, always return true.
inline bool HasValidSource();
-#ifdef OBJECT_PRINT
- inline void ScriptPrint() {
- ScriptPrint(stdout);
- }
- void ScriptPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(Script)
DECLARE_VERIFIER(Script)
static const int kSourceOffset = HeapObject::kHeaderSize;
@@ -5378,6 +5622,7 @@ class SharedFunctionInfo: public HeapObject {
// [code]: Function code.
DECL_ACCESSORS(code, Code)
+ inline void ReplaceCode(Code* code);
// [optimized_code_map]: Map from native context to optimized code
// and a shared literals array or Smi 0 if none.
@@ -5393,7 +5638,7 @@ class SharedFunctionInfo: public HeapObject {
void InstallFromOptimizedCodeMap(JSFunction* function, int index);
// Clear optimized code map.
- void ClearOptimizedCodeMap();
+ inline void ClearOptimizedCodeMap();
// Add a new entry to the optimized code map.
static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
@@ -5768,12 +6013,7 @@ class SharedFunctionInfo: public HeapObject {
// Dispatched behavior.
// Set max_length to -1 for unlimited length.
void SourceCodePrint(StringStream* accumulator, int max_length);
-#ifdef OBJECT_PRINT
- inline void SharedFunctionInfoPrint() {
- SharedFunctionInfoPrint(stdout);
- }
- void SharedFunctionInfoPrint(FILE* out);
-#endif
+ DECLARE_PRINTER(SharedFunctionInfo)
DECLARE_VERIFIER(SharedFunctionInfo)
void ResetForNewContext(int new_ic_age);
@@ -5901,10 +6141,10 @@ class SharedFunctionInfo: public HeapObject {
// Bit positions in start_position_and_type.
// The source code start position is in the 30 most significant bits of
// the start_position_and_type field.
- static const int kIsExpressionBit = 0;
- static const int kIsTopLevelBit = 1;
+ static const int kIsExpressionBit = 0;
+ static const int kIsTopLevelBit = 1;
static const int kStartPositionShift = 2;
- static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1);
+ static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1);
// Bit positions in compiler_hints.
static const int kCodeAgeSize = 3;
@@ -6002,12 +6242,7 @@ class JSModule: public JSObject {
static inline JSModule* cast(Object* obj);
// Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void JSModulePrint() {
- JSModulePrint(stdout);
- }
- void JSModulePrint(FILE* out);
-#endif
+ DECLARE_PRINTER(JSModule)
DECLARE_VERIFIER(JSModule)
// Layout description.
@@ -6043,6 +6278,7 @@ class JSFunction: public JSObject {
// 8.6.2, page 27.
inline Code* code();
inline void set_code(Code* code);
+ inline void set_code_no_write_barrier(Code* code);
inline void ReplaceCode(Code* code);
inline Code* unchecked_code();
@@ -6063,6 +6299,8 @@ class JSFunction: public JSObject {
// recompiled the next time it is executed.
void MarkForLazyRecompilation();
void MarkForParallelRecompilation();
+ void MarkForInstallingRecompiledCode();
+ void MarkInRecompileQueue();
// Helpers to compile this function. Returns true on success, false on
// failure (e.g., stack overflow during compilation).
@@ -6078,6 +6316,7 @@ class JSFunction: public JSObject {
// recompilation.
inline bool IsMarkedForLazyRecompilation();
inline bool IsMarkedForParallelRecompilation();
+ inline bool IsMarkedForInstallingRecompiledCode();
// Tells whether or not the function is on the parallel
// recompilation queue.
@@ -6161,12 +6400,7 @@ class JSFunction: public JSObject {
void JSFunctionIterateBody(int object_size, ObjectVisitor* v);
// Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void JSFunctionPrint() {
- JSFunctionPrint(stdout);
- }
- void JSFunctionPrint(FILE* out);
-#endif
+ DECLARE_PRINTER(JSFunction)
DECLARE_VERIFIER(JSFunction)
// Returns the number of allocated literals.
@@ -6175,6 +6409,18 @@ class JSFunction: public JSObject {
// Retrieve the native context from a function's literal array.
static Context* NativeContextFromLiterals(FixedArray* literals);
+#ifdef DEBUG
+ bool FunctionsInFunctionListShareSameCode() {
+ Object* current = this;
+ while (!current->IsUndefined()) {
+ JSFunction* function = JSFunction::cast(current);
+ current = function->next_function_link();
+ if (function->code() != this->code()) return false;
+ }
+ return true;
+ }
+#endif
+
// Layout descriptors. The last property (from kNonWeakFieldsEndOffset to
// kSize) is weak and has special handling during garbage collection.
static const int kCodeEntryOffset = JSObject::kHeaderSize;
@@ -6220,12 +6466,7 @@ class JSGlobalProxy : public JSObject {
static inline JSGlobalProxy* cast(Object* obj);
// Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void JSGlobalProxyPrint() {
- JSGlobalProxyPrint(stdout);
- }
- void JSGlobalProxyPrint(FILE* out);
-#endif
+ DECLARE_PRINTER(JSGlobalProxy)
DECLARE_VERIFIER(JSGlobalProxy)
// Layout description.
@@ -6263,7 +6504,7 @@ class GlobalObject: public JSObject {
// by throwing an exception. This is for the debug and builtins global
// objects, where it is known which properties can be expected to be present
// on the object.
- Object* GetPropertyNoExceptionThrown(String* key) {
+ Object* GetPropertyNoExceptionThrown(Name* key) {
Object* answer = GetProperty(key)->ToObjectUnchecked();
return answer;
}
@@ -6271,10 +6512,10 @@ class GlobalObject: public JSObject {
// Ensure that the global object has a cell for the given property name.
static Handle<JSGlobalPropertyCell> EnsurePropertyCell(
Handle<GlobalObject> global,
- Handle<String> name);
+ Handle<Name> name);
// TODO(kmillikin): This function can be eliminated once the stub cache is
- // full handlified (and the static helper can be written directly).
- MUST_USE_RESULT MaybeObject* EnsurePropertyCell(String* name);
+ // fully handlified (and the static helper can be written directly).
+ MUST_USE_RESULT MaybeObject* EnsurePropertyCell(Name* name);
// Casting.
static inline GlobalObject* cast(Object* obj);
@@ -6298,12 +6539,7 @@ class JSGlobalObject: public GlobalObject {
static inline JSGlobalObject* cast(Object* obj);
// Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void JSGlobalObjectPrint() {
- JSGlobalObjectPrint(stdout);
- }
- void JSGlobalObjectPrint(FILE* out);
-#endif
+ DECLARE_PRINTER(JSGlobalObject)
DECLARE_VERIFIER(JSGlobalObject)
// Layout description.
@@ -6330,12 +6566,7 @@ class JSBuiltinsObject: public GlobalObject {
static inline JSBuiltinsObject* cast(Object* obj);
// Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void JSBuiltinsObjectPrint() {
- JSBuiltinsObjectPrint(stdout);
- }
- void JSBuiltinsObjectPrint(FILE* out);
-#endif
+ DECLARE_PRINTER(JSBuiltinsObject)
DECLARE_VERIFIER(JSBuiltinsObject)
// Layout description. The size of the builtins object includes
@@ -6371,12 +6602,7 @@ class JSValue: public JSObject {
static inline JSValue* cast(Object* obj);
// Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void JSValuePrint() {
- JSValuePrint(stdout);
- }
- void JSValuePrint(FILE* out);
-#endif
+ DECLARE_PRINTER(JSValue)
DECLARE_VERIFIER(JSValue)
// Layout description.
@@ -6425,12 +6651,7 @@ class JSDate: public JSObject {
// Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void JSDatePrint() {
- JSDatePrint(stdout);
- }
- void JSDatePrint(FILE* out);
-#endif
+ DECLARE_PRINTER(JSDate)
DECLARE_VERIFIER(JSDate)
// The order is important. It must be kept in sync with date macros
@@ -6522,12 +6743,7 @@ class JSMessageObject: public JSObject {
static inline JSMessageObject* cast(Object* obj);
// Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void JSMessageObjectPrint() {
- JSMessageObjectPrint(stdout);
- }
- void JSMessageObjectPrint(FILE* out);
-#endif
+ DECLARE_PRINTER(JSMessageObject)
DECLARE_VERIFIER(JSMessageObject)
// Layout description.
@@ -6704,8 +6920,9 @@ class CompilationCacheShape : public BaseShape<HashTableKey*> {
return key->HashForObject(object);
}
- MUST_USE_RESULT static MaybeObject* AsObject(HashTableKey* key) {
- return key->AsObject();
+ MUST_USE_RESULT static MaybeObject* AsObject(Heap* heap,
+ HashTableKey* key) {
+ return key->AsObject(heap);
}
static const int kPrefixSize = 0;
@@ -6750,11 +6967,11 @@ class CodeCache: public Struct {
DECL_ACCESSORS(normal_type_cache, Object)
// Add the code object to the cache.
- MUST_USE_RESULT MaybeObject* Update(String* name, Code* code);
+ MUST_USE_RESULT MaybeObject* Update(Name* name, Code* code);
// Lookup code object in the cache. Returns code object if found and undefined
// if not.
- Object* Lookup(String* name, Code::Flags flags);
+ Object* Lookup(Name* name, Code::Flags flags);
// Get the internal index of a code object in the cache. Returns -1 if the
// code object is not in that cache. This index can be used to later call
@@ -6767,12 +6984,8 @@ class CodeCache: public Struct {
static inline CodeCache* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void CodeCachePrint() {
- CodeCachePrint(stdout);
- }
- void CodeCachePrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(CodeCache)
DECLARE_VERIFIER(CodeCache)
static const int kDefaultCacheOffset = HeapObject::kHeaderSize;
@@ -6781,10 +6994,10 @@ class CodeCache: public Struct {
static const int kSize = kNormalTypeCacheOffset + kPointerSize;
private:
- MUST_USE_RESULT MaybeObject* UpdateDefaultCache(String* name, Code* code);
- MUST_USE_RESULT MaybeObject* UpdateNormalTypeCache(String* name, Code* code);
- Object* LookupDefaultCache(String* name, Code::Flags flags);
- Object* LookupNormalTypeCache(String* name, Code::Flags flags);
+ MUST_USE_RESULT MaybeObject* UpdateDefaultCache(Name* name, Code* code);
+ MUST_USE_RESULT MaybeObject* UpdateNormalTypeCache(Name* name, Code* code);
+ Object* LookupDefaultCache(Name* name, Code::Flags flags);
+ Object* LookupNormalTypeCache(Name* name, Code::Flags flags);
// Code cache layout of the default cache. Elements are alternating name and
// code objects for non normal load/store/call IC's.
@@ -6810,8 +7023,9 @@ class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
return key->HashForObject(object);
}
- MUST_USE_RESULT static MaybeObject* AsObject(HashTableKey* key) {
- return key->AsObject();
+ MUST_USE_RESULT static MaybeObject* AsObject(Heap* heap,
+ HashTableKey* key) {
+ return key->AsObject(heap);
}
static const int kPrefixSize = 0;
@@ -6822,10 +7036,10 @@ class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
class CodeCacheHashTable: public HashTable<CodeCacheHashTableShape,
HashTableKey*> {
public:
- Object* Lookup(String* name, Code::Flags flags);
- MUST_USE_RESULT MaybeObject* Put(String* name, Code* code);
+ Object* Lookup(Name* name, Code::Flags flags);
+ MUST_USE_RESULT MaybeObject* Put(Name* name, Code* code);
- int GetIndex(String* name, Code::Flags flags);
+ int GetIndex(Name* name, Code::Flags flags);
void RemoveByIndex(int index);
static inline CodeCacheHashTable* cast(Object* obj);
@@ -6856,12 +7070,8 @@ class PolymorphicCodeCache: public Struct {
static inline PolymorphicCodeCache* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void PolymorphicCodeCachePrint() {
- PolymorphicCodeCachePrint(stdout);
- }
- void PolymorphicCodeCachePrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(PolymorphicCodeCache)
DECLARE_VERIFIER(PolymorphicCodeCache)
static const int kCacheOffset = HeapObject::kHeaderSize;
@@ -6909,12 +7119,8 @@ class TypeFeedbackInfo: public Struct {
static inline TypeFeedbackInfo* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void TypeFeedbackInfoPrint() {
- TypeFeedbackInfoPrint(stdout);
- }
- void TypeFeedbackInfoPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(TypeFeedbackInfo)
DECLARE_VERIFIER(TypeFeedbackInfo)
static const int kStorage1Offset = HeapObject::kHeaderSize;
@@ -6940,6 +7146,38 @@ class TypeFeedbackInfo: public Struct {
};
+enum AllocationSiteMode {
+ DONT_TRACK_ALLOCATION_SITE,
+ TRACK_ALLOCATION_SITE,
+ LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE
+};
+
+
+class AllocationSiteInfo: public Struct {
+ public:
+ DECL_ACCESSORS(payload, Object)
+
+ static inline AllocationSiteInfo* cast(Object* obj);
+
+ DECLARE_PRINTER(AllocationSiteInfo)
+ DECLARE_VERIFIER(AllocationSiteInfo)
+
+ // Returns NULL if no AllocationSiteInfo is available for object.
+ static AllocationSiteInfo* FindForJSObject(JSObject* object);
+
+ static AllocationSiteMode GetMode(ElementsKind boilerplate_elements_kind);
+ static AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
+
+ static const int kPayloadOffset = HeapObject::kHeaderSize;
+ static const int kSize = kPayloadOffset + kPointerSize;
+ static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024;
+
+ bool GetElementsKindPayload(ElementsKind* kind);
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSiteInfo);
+};
+
+
// Representation of a slow alias as part of a non-strict arguments objects.
// For fast aliases (if HasNonStrictArgumentsElements()):
// - the parameter map contains an index into the context
@@ -6955,12 +7193,8 @@ class AliasedArgumentsEntry: public Struct {
static inline AliasedArgumentsEntry* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void AliasedArgumentsEntryPrint() {
- AliasedArgumentsEntryPrint(stdout);
- }
- void AliasedArgumentsEntryPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(AliasedArgumentsEntry)
DECLARE_VERIFIER(AliasedArgumentsEntry)
static const int kAliasedContextSlot = HeapObject::kHeaderSize;
@@ -6979,30 +7213,15 @@ class StringHasher {
public:
explicit inline StringHasher(int length, uint32_t seed);
- // Returns true if the hash of this string can be computed without
- // looking at the contents.
- inline bool has_trivial_hash();
-
- // Add a character to the hash and update the array index calculation.
- inline void AddCharacter(uint32_t c);
+ template <typename schar>
+ static inline uint32_t HashSequentialString(const schar* chars,
+ int length,
+ uint32_t seed);
- // Adds a character to the hash but does not update the array index
- // calculation. This can only be called when it has been verified
- // that the input is not an array index.
- inline void AddCharacterNoIndex(uint32_t c);
-
- // Add a character above 0xffff as a surrogate pair. These can get into
- // the hasher through the routines that take a UTF-8 string and make a symbol.
- void AddSurrogatePair(uc32 c);
- void AddSurrogatePairNoIndex(uc32 c);
-
- // Returns the value to store in the hash field of a string with
- // the given length and contents.
- uint32_t GetHashField();
-
- // Returns true if the characters seen so far make up a legal array
- // index.
- bool is_array_index() { return is_array_index_; }
+ // Reads all the data, even for long strings and computes the utf16 length.
+ static uint32_t ComputeUtf8Hash(Vector<const char> chars,
+ uint32_t seed,
+ int* utf16_length_out);
// Calculated hash value for a string consisting of 1 to
// String::kMaxArrayIndexSize digits with no leading zeros (except "0").
@@ -7014,51 +7233,36 @@ class StringHasher {
// use 27 instead.
static const int kZeroHash = 27;
- private:
- uint32_t array_index() {
- ASSERT(is_array_index());
- return array_index_;
- }
-
- 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 AddCharacterCore(uint32_t running_hash, uint16_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_;
- 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();
+ protected:
+ // Returns the value to store in the hash field of a string with
+ // the given length and contents.
+ uint32_t GetHashField();
+ // Returns true if the hash of this string can be computed without
+ // looking at the contents.
+ inline bool has_trivial_hash();
+ // Adds a block of characters to the hash.
+ template<typename Char>
+ inline void AddCharacters(const Char* chars, int len);
private:
+ // Add a character to the hash.
+ inline void AddCharacter(uint16_t c);
+ // Update index. Returns true if string is still an index.
+ inline bool UpdateIndex(uint16_t c);
+
int length_;
uint32_t raw_running_hash_;
uint32_t array_index_;
bool is_array_index_;
- char first_char_;
+ bool is_first_char_;
+ DISALLOW_COPY_AND_ASSIGN(StringHasher);
};
-// Calculates string hash.
-template <typename schar>
-inline uint32_t HashSequentialString(const schar* chars,
- int length,
- uint32_t seed);
-
-
// The characteristics of a string are stored in its map. Retrieving these
// few bits of information is moderately expensive, involving two memory
// loads where the second is dependent on the first. To improve efficiency
@@ -7084,7 +7288,7 @@ class StringShape BASE_EMBEDDED {
inline bool IsExternalTwoByte();
inline bool IsSequentialAscii();
inline bool IsSequentialTwoByte();
- inline bool IsSymbol();
+ inline bool IsInternalized();
inline StringRepresentationTag representation_tag();
inline uint32_t encoding_tag();
inline uint32_t full_representation_tag();
@@ -7108,6 +7312,112 @@ class StringShape BASE_EMBEDDED {
};
+// The Name abstract class captures anything that can be used as a property
+// name, i.e., strings and symbols. All names store a hash value.
+class Name: public HeapObject {
+ public:
+ // Get and set the hash field of the name.
+ inline uint32_t hash_field();
+ inline void set_hash_field(uint32_t value);
+
+ // Tells whether the hash code has been computed.
+ inline bool HasHashCode();
+
+ // Returns a hash value used for the property table
+ inline uint32_t Hash();
+
+ // Equality operations.
+ inline bool Equals(Name* other);
+
+ // Conversion.
+ inline bool AsArrayIndex(uint32_t* index);
+
+ // Casting.
+ static inline Name* cast(Object* obj);
+
+ DECLARE_PRINTER(Name)
+
+ // Layout description.
+ static const int kHashFieldOffset = HeapObject::kHeaderSize;
+ static const int kSize = kHashFieldOffset + kPointerSize;
+
+ // Mask constant for checking if a name has a computed hash code
+ // and if it is a string that is an array index. The least significant bit
+ // indicates whether a hash code has been computed. If the hash code has
+ // been computed the 2nd bit tells whether the string can be used as an
+ // array index.
+ static const int kHashNotComputedMask = 1;
+ static const int kIsNotArrayIndexMask = 1 << 1;
+ static const int kNofHashBitFields = 2;
+
+ // Shift constant retrieving hash code from hash field.
+ static const int kHashShift = kNofHashBitFields;
+
+ // Only these bits are relevant in the hash, since the top two are shifted
+ // out.
+ static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
+
+ // Array index strings this short can keep their index in the hash field.
+ static const int kMaxCachedArrayIndexLength = 7;
+
+ // For strings which are array indexes the hash value has the string length
+ // mixed into the hash, mainly to avoid a hash value of zero which would be
+ // the case for the string '0'. 24 bits are used for the array index value.
+ static const int kArrayIndexValueBits = 24;
+ static const int kArrayIndexLengthBits =
+ kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
+
+ STATIC_CHECK((kArrayIndexLengthBits > 0));
+
+ static const int kArrayIndexHashLengthShift =
+ kArrayIndexValueBits + kNofHashBitFields;
+
+ static const int kArrayIndexHashMask = (1 << kArrayIndexHashLengthShift) - 1;
+
+ static const int kArrayIndexValueMask =
+ ((1 << kArrayIndexValueBits) - 1) << kHashShift;
+
+ // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
+ // could use a mask to test if the length of string is less than or equal to
+ // kMaxCachedArrayIndexLength.
+ STATIC_CHECK(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
+
+ static const int kContainsCachedArrayIndexMask =
+ (~kMaxCachedArrayIndexLength << kArrayIndexHashLengthShift) |
+ kIsNotArrayIndexMask;
+
+ // Value of empty hash field indicating that the hash is not computed.
+ static const int kEmptyHashField =
+ kIsNotArrayIndexMask | kHashNotComputedMask;
+
+ protected:
+ static inline bool IsHashFieldComputed(uint32_t field);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Name);
+};
+
+
+// ES6 symbols.
+class Symbol: public Name {
+ public:
+ // Casting.
+ static inline Symbol* cast(Object* obj);
+
+ // Dispatched behavior.
+ DECLARE_PRINTER(Symbol)
+ DECLARE_VERIFIER(Symbol)
+
+ // Layout description.
+ static const int kSize = Name::kSize;
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Symbol);
+};
+
+
+class ConsString;
+
// The String abstract class captures JavaScript string values:
//
// Ecma-262:
@@ -7116,8 +7426,10 @@ class StringShape BASE_EMBEDDED {
// ordered sequence of zero or more 16-bit unsigned integer values.
//
// All string values have a length field.
-class String: public HeapObject {
+class String: public Name {
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
@@ -7132,11 +7444,11 @@ class String: public HeapObject {
// Returns true if the structure contains two-byte content.
bool IsTwoByte() { return state_ == TWO_BYTE; }
- // Return the ASCII content of the string. Only use if IsAscii() returns
+ // Return the one byte content of the string. Only use if IsAscii() returns
// true.
- Vector<const char> ToAsciiVector() {
+ Vector<const uint8_t> ToOneByteVector() {
ASSERT_EQ(ASCII, state_);
- return Vector<const char>::cast(buffer_);
+ return buffer_;
}
// Return the two-byte content of the string. Only use if IsTwoByte()
// returns true.
@@ -7149,15 +7461,15 @@ class String: public HeapObject {
enum State { NON_FLAT, ASCII, TWO_BYTE };
// Constructors only used by String::GetFlatContent().
- explicit FlatContent(Vector<const char> chars)
- : buffer_(Vector<const byte>::cast(chars)),
+ explicit FlatContent(Vector<const uint8_t> chars)
+ : buffer_(chars),
state_(ASCII) { }
explicit FlatContent(Vector<const uc16> chars)
: buffer_(Vector<const byte>::cast(chars)),
state_(TWO_BYTE) { }
FlatContent() : buffer_(), state_(NON_FLAT) { }
- Vector<const byte> buffer_;
+ Vector<const uint8_t> buffer_;
State state_;
friend class String;
@@ -7167,27 +7479,25 @@ class String: public HeapObject {
inline int length();
inline void set_length(int value);
- // Get and set the hash field of the string.
- inline uint32_t hash_field();
- inline void set_hash_field(uint32_t value);
-
// Returns whether this string has only ASCII chars, i.e. all of them can
// 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
// possible.
inline bool HasOnlyAsciiChars();
+ inline bool IsOneByteConvertible();
+
// Get and set individual two byte chars in the string.
inline void Set(int index, uint16_t value);
// Get individual two byte char in the string. Repeated calls
@@ -7238,8 +7548,8 @@ class String: public HeapObject {
// String equality operations.
inline bool Equals(String* other);
- bool IsEqualTo(Vector<const char> str);
- bool IsAsciiEqualTo(Vector<const char> str);
+ bool IsUtf8EqualTo(Vector<const char> str);
+ bool IsOneByteEqualTo(Vector<const uint8_t> str);
bool IsTwoByteEqualTo(Vector<const uc16> str);
// Return a UTF8 representation of the string. The string is null
@@ -7269,19 +7579,7 @@ class String: public HeapObject {
SmartArrayPointer<uc16> ToWideCString(
RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL);
- // Tells whether the hash code has been computed.
- inline bool HasHashCode();
-
- // Returns a hash value used for the property table
- inline uint32_t Hash();
-
- static uint32_t ComputeHashField(unibrow::CharacterStream* buffer,
- int length,
- uint32_t seed);
-
- static bool ComputeArrayIndex(unibrow::CharacterStream* buffer,
- uint32_t* index,
- int length);
+ bool ComputeArrayIndex(uint32_t* index);
// Externalization.
bool MakeExternal(v8::String::ExternalStringResource* resource);
@@ -7313,69 +7611,18 @@ class String: public HeapObject {
inline bool IsFlat();
// Layout description.
- static const int kLengthOffset = HeapObject::kHeaderSize;
- static const int kHashFieldOffset = kLengthOffset + kPointerSize;
- static const int kSize = kHashFieldOffset + kPointerSize;
+ static const int kLengthOffset = Name::kSize;
+ static const int kSize = kLengthOffset + kPointerSize;
// Maximum number of characters to consider when trying to convert a string
// value into an array index.
static const int kMaxArrayIndexSize = 10;
-
- // Max ASCII char code.
- static const int kMaxAsciiCharCode = unibrow::Utf8::kMaxOneByteChar;
- static const unsigned kMaxAsciiCharCodeU = unibrow::Utf8::kMaxOneByteChar;
- static const int kMaxUtf16CodeUnit = 0xffff;
-
- // Mask constant for checking if a string has a computed hash code
- // and if it is an array index. The least significant bit indicates
- // whether a hash code has been computed. If the hash code has been
- // computed the 2nd bit tells whether the string can be used as an
- // array index.
- static const int kHashNotComputedMask = 1;
- static const int kIsNotArrayIndexMask = 1 << 1;
- static const int kNofHashBitFields = 2;
-
- // Shift constant retrieving hash code from hash field.
- static const int kHashShift = kNofHashBitFields;
-
- // Only these bits are relevant in the hash, since the top two are shifted
- // out.
- static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
-
- // Array index strings this short can keep their index in the hash
- // field.
- static const int kMaxCachedArrayIndexLength = 7;
-
- // For strings which are array indexes the hash value has the string length
- // mixed into the hash, mainly to avoid a hash value of zero which would be
- // the case for the string '0'. 24 bits are used for the array index value.
- static const int kArrayIndexValueBits = 24;
- static const int kArrayIndexLengthBits =
- kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
-
- STATIC_CHECK((kArrayIndexLengthBits > 0));
STATIC_CHECK(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
- static const int kArrayIndexHashLengthShift =
- kArrayIndexValueBits + kNofHashBitFields;
-
- static const int kArrayIndexHashMask = (1 << kArrayIndexHashLengthShift) - 1;
-
- static const int kArrayIndexValueMask =
- ((1 << kArrayIndexValueBits) - 1) << kHashShift;
-
- // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
- // could use a mask to test if the length of string is less than or equal to
- // kMaxCachedArrayIndexLength.
- STATIC_CHECK(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
-
- static const int kContainsCachedArrayIndexMask =
- (~kMaxCachedArrayIndexLength << kArrayIndexHashLengthShift) |
- kIsNotArrayIndexMask;
-
- // Value of empty hash field indicating that the hash is not computed.
- static const int kEmptyHashField =
- kIsNotArrayIndexMask | kHashNotComputedMask;
+ // Max char codes.
+ static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
+ static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
+ static const int kMaxUtf16CodeUnit = 0xffff;
// Value of hash field containing computed hash equal to zero.
static const int kEmptyStringHash = kIsNotArrayIndexMask;
@@ -7394,18 +7641,6 @@ class String: public HeapObject {
const uc16* GetTwoByteData();
const uc16* GetTwoByteData(unsigned start);
- // Support for StringInputBuffer
- static const unibrow::byte* ReadBlock(String* input,
- unibrow::byte* util_buffer,
- unsigned capacity,
- unsigned* remaining,
- unsigned* offset);
- static const unibrow::byte* ReadBlock(String** input,
- unibrow::byte* util_buffer,
- unsigned capacity,
- unsigned* remaining,
- unsigned* offset);
-
// Helper function for flattening strings.
template <typename sinkchar>
static void WriteToFlat(String* source,
@@ -7420,7 +7655,7 @@ class String: public HeapObject {
const char* start = chars;
const char* limit = chars + length;
#ifdef V8_HOST_CAN_READ_UNALIGNED
- ASSERT(kMaxAsciiCharCode == 0x7F);
+ ASSERT(unibrow::Utf8::kMaxOneByteChar == 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) {
@@ -7430,7 +7665,7 @@ class String: public HeapObject {
}
#endif
while (chars < limit) {
- if (static_cast<uint8_t>(*chars) > kMaxAsciiCharCodeU) {
+ if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
return static_cast<int>(chars - start);
}
++chars;
@@ -7442,55 +7677,57 @@ class String: public HeapObject {
return NonAsciiStart(chars, length) >= length;
}
- static inline int NonAsciiStart(const uc16* chars, int length) {
+ static inline bool IsAscii(const uint8_t* chars, int length) {
+ return
+ NonAsciiStart(reinterpret_cast<const char*>(chars), length) >= length;
+ }
+
+ static inline int NonOneByteStart(const uc16* chars, int length) {
const uc16* limit = chars + length;
const uc16* start = chars;
while (chars < limit) {
- if (*chars > kMaxAsciiCharCodeU) return static_cast<int>(chars - start);
+ if (*chars > kMaxOneByteCharCodeU) return static_cast<int>(chars - start);
++chars;
}
return static_cast<int>(chars - start);
}
- static inline bool IsAscii(const uc16* chars, int length) {
- return NonAsciiStart(chars, length) >= length;
+ static inline bool IsOneByte(const uc16* chars, int length) {
+ return NonOneByteStart(chars, length) >= length;
}
- protected:
- class ReadBlockBuffer {
- public:
- ReadBlockBuffer(unibrow::byte* util_buffer_,
- unsigned cursor_,
- unsigned capacity_,
- unsigned remaining_) :
- util_buffer(util_buffer_),
- cursor(cursor_),
- capacity(capacity_),
- remaining(remaining_) {
- }
- unibrow::byte* util_buffer;
- unsigned cursor;
- unsigned capacity;
- unsigned remaining;
- };
+ // TODO(dcarney): Replace all instances of this with VisitFlat.
+ template<class Visitor, class ConsOp>
+ static inline void Visit(String* string,
+ unsigned offset,
+ Visitor& visitor,
+ ConsOp& cons_op,
+ int32_t type,
+ unsigned length);
+
+ template<class Visitor>
+ static inline ConsString* VisitFlat(Visitor* visitor,
+ String* string,
+ int offset,
+ int length,
+ int32_t type);
- static inline const unibrow::byte* ReadBlock(String* input,
- ReadBlockBuffer* buffer,
- unsigned* offset,
- unsigned max_chars);
- static void ReadBlockIntoBuffer(String* input,
- ReadBlockBuffer* buffer,
- unsigned* offset_ptr,
- unsigned max_chars);
+ template<class Visitor>
+ static inline ConsString* VisitFlat(Visitor* visitor,
+ String* string,
+ int offset = 0) {
+ int32_t type = string->map()->instance_type();
+ return VisitFlat(visitor, string, offset, string->length(), type);
+ }
private:
+ friend class Name;
+
// Try to flatten the top level ConsString that is hiding behind this
// string. This is a no-op unless the string is a ConsString. Flatten
// mutates the ConsString and might return a failure.
MUST_USE_RESULT MaybeObject* SlowTryFlatten(PretenureFlag pretenure);
- static inline bool IsHashFieldComputed(uint32_t field);
-
// Slow case of String::Equals. This implementation works on any strings
// but it is most efficient on strings that are almost flat.
bool SlowEquals(String* other);
@@ -7514,6 +7751,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);
};
@@ -7521,26 +7763,26 @@ 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();
- inline char* GetChars();
+ inline uint8_t* 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) {
@@ -7553,18 +7795,8 @@ class SeqAsciiString: public SeqString {
// Q.v. String::kMaxLength which is the maximal size of concatenated strings.
static const int kMaxLength = (kMaxSize - kHeaderSize);
- // Support for StringInputBuffer.
- inline void SeqAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
- unsigned* offset,
- unsigned chars);
- inline const unibrow::byte* SeqAsciiStringReadBlock(unsigned* remaining,
- unsigned* offset,
- unsigned chars);
-
- DECLARE_VERIFIER(SeqAsciiString)
-
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(SeqAsciiString);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
};
@@ -7605,11 +7837,6 @@ class SeqTwoByteString: public SeqString {
// Q.v. String::kMaxLength which is the maximal size of concatenated strings.
static const int kMaxLength = (kMaxSize - kHeaderSize) / sizeof(uint16_t);
- // Support for StringInputBuffer.
- inline void SeqTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
- unsigned* offset_ptr,
- unsigned chars);
-
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
};
@@ -7652,14 +7879,6 @@ class ConsString: public String {
static const int kSecondOffset = kFirstOffset + kPointerSize;
static const int kSize = kSecondOffset + kPointerSize;
- // Support for StringInputBuffer.
- inline const unibrow::byte* ConsStringReadBlock(ReadBlockBuffer* buffer,
- unsigned* offset_ptr,
- unsigned chars);
- inline void ConsStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
- unsigned* offset_ptr,
- unsigned chars);
-
// Minimum length for a cons string.
static const int kMinLength = 13;
@@ -7704,13 +7923,6 @@ class SlicedString: public String {
static const int kOffsetOffset = kParentOffset + kPointerSize;
static const int kSize = kOffsetOffset + kPointerSize;
- // Support for StringInputBuffer
- inline const unibrow::byte* SlicedStringReadBlock(ReadBlockBuffer* buffer,
- unsigned* offset_ptr,
- unsigned chars);
- inline void SlicedStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
- unsigned* offset_ptr,
- unsigned chars);
// Minimum length for a sliced string.
static const int kMinLength = 13;
@@ -7745,6 +7957,9 @@ class ExternalString: public String {
static const int kResourceDataOffset = kResourceOffset + kPointerSize;
static const int kSize = kResourceDataOffset + kPointerSize;
+ static const int kMaxShortLength =
+ (kShortSize - SeqString::kHeaderSize) / kCharSize;
+
// Return whether external string is short (data pointer is not cached).
inline bool is_short();
@@ -7773,7 +7988,7 @@ class ExternalAsciiString: public ExternalString {
// which the pointer cache has to be refreshed.
inline void update_data_cache();
- inline const char* GetChars();
+ inline const uint8_t* GetChars();
// Dispatched behavior.
inline uint16_t ExternalAsciiStringGet(int index);
@@ -7787,14 +8002,6 @@ class ExternalAsciiString: public ExternalString {
template<typename StaticVisitor>
inline void ExternalAsciiStringIterateBody();
- // Support for StringInputBuffer.
- const unibrow::byte* ExternalAsciiStringReadBlock(unsigned* remaining,
- unsigned* offset,
- unsigned chars);
- inline void ExternalAsciiStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
- unsigned* offset,
- unsigned chars);
-
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalAsciiString);
};
@@ -7835,12 +8042,6 @@ class ExternalTwoByteString: public ExternalString {
template<typename StaticVisitor>
inline void ExternalTwoByteStringIterateBody();
-
- // Support for StringInputBuffer.
- void ExternalTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
- unsigned* offset_ptr,
- unsigned chars);
-
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString);
};
@@ -7887,32 +8088,82 @@ class FlatStringReader : public Relocatable {
};
-// Note that StringInputBuffers are not valid across a GC! To fix this
-// it would have to store a String Handle instead of a String* and
-// AsciiStringReadBlock would have to be modified to use memcpy.
-//
-// StringInputBuffer is able to traverse any string regardless of how
-// deeply nested a sequence of ConsStrings it is made of. However,
-// performance will be better if deep strings are flattened before they
-// are traversed. Since flattening requires memory allocation this is
-// not always desirable, however (esp. in debugging situations).
-class StringInputBuffer: public unibrow::InputBuffer<String, String*, 1024> {
+// A ConsStringOp that returns null.
+// Useful when the operation to apply on a ConsString
+// requires an expensive data structure.
+class ConsStringNullOp {
public:
- virtual void Seek(unsigned pos);
- inline StringInputBuffer(): unibrow::InputBuffer<String, String*, 1024>() {}
- explicit inline StringInputBuffer(String* backing):
- unibrow::InputBuffer<String, String*, 1024>(backing) {}
+ inline ConsStringNullOp() {}
+ static inline String* Operate(String*, unsigned*, int32_t*, unsigned*);
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ConsStringNullOp);
};
-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) {}
+ inline ConsStringIteratorOp() {}
+ String* Operate(String* string,
+ unsigned* offset_out,
+ int32_t* type_out,
+ unsigned* length_out);
+ inline String* ContinueOperation(int32_t* type_out, unsigned* length_out);
+ 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);
+
+ inline void PushLeft(ConsString* string);
+ inline void PushRight(ConsString* string);
+ inline void AdjustMaximumDepth();
+ inline void Pop();
+ String* NextLeaf(bool* blew_stack, int32_t* type_out, unsigned* length_out);
+ String* Search(unsigned* offset_out,
+ int32_t* type_out,
+ unsigned* length_out);
+
+ unsigned depth_;
+ unsigned maximum_depth_;
+ // Stack must always contain only frames for which right traversal
+ // has not yet been performed.
+ ConsString* frames_[kStackSize];
+ unsigned consumed_;
+ ConsString* root_;
+ DISALLOW_COPY_AND_ASSIGN(ConsStringIteratorOp);
+};
+
+
+// Note: this class is not GC-safe.
+class StringCharacterStream {
+ public:
+ inline StringCharacterStream(String* string,
+ ConsStringIteratorOp* op,
+ unsigned offset = 0);
+ inline uint16_t GetNext();
+ inline bool HasMore();
+ inline void Reset(String* string, unsigned offset = 0);
+ 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);
};
@@ -7996,15 +8247,10 @@ class JSGlobalPropertyCell: public HeapObject {
return address() + kValueOffset;
}
+ // Dispatched behavior.
+ DECLARE_PRINTER(JSGlobalPropertyCell)
DECLARE_VERIFIER(JSGlobalPropertyCell)
-#ifdef OBJECT_PRINT
- inline void JSGlobalPropertyCellPrint() {
- JSGlobalPropertyCellPrint(stdout);
- }
- void JSGlobalPropertyCellPrint(FILE* out);
-#endif
-
// Layout description.
static const int kValueOffset = HeapObject::kHeaderSize;
static const int kSize = kValueOffset + kPointerSize;
@@ -8030,19 +8276,19 @@ class JSProxy: public JSReceiver {
// Casting.
static inline JSProxy* cast(Object* obj);
- bool HasPropertyWithHandler(String* name);
+ bool HasPropertyWithHandler(Name* name);
bool HasElementWithHandler(uint32_t index);
MUST_USE_RESULT MaybeObject* GetPropertyWithHandler(
Object* receiver,
- String* name);
+ Name* name);
MUST_USE_RESULT MaybeObject* GetElementWithHandler(
Object* receiver,
uint32_t index);
MUST_USE_RESULT MaybeObject* SetPropertyWithHandler(
JSReceiver* receiver,
- String* name,
+ Name* name,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode);
@@ -8058,14 +8304,14 @@ class JSProxy: public JSReceiver {
// otherwise set it to false.
MUST_USE_RESULT MaybeObject* SetPropertyViaPrototypesWithHandler(
JSReceiver* receiver,
- String* name,
+ Name* name,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
bool* done);
MUST_USE_RESULT MaybeObject* DeletePropertyWithHandler(
- String* name,
+ Name* name,
DeleteMode mode);
MUST_USE_RESULT MaybeObject* DeleteElementWithHandler(
uint32_t index,
@@ -8073,7 +8319,7 @@ class JSProxy: public JSReceiver {
MUST_USE_RESULT PropertyAttributes GetPropertyAttributeWithHandler(
JSReceiver* receiver,
- String* name);
+ Name* name);
MUST_USE_RESULT PropertyAttributes GetElementAttributeWithHandler(
JSReceiver* receiver,
uint32_t index);
@@ -8094,12 +8340,7 @@ class JSProxy: public JSReceiver {
Handle<Object> args[]);
// Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void JSProxyPrint() {
- JSProxyPrint(stdout);
- }
- void JSProxyPrint(FILE* out);
-#endif
+ DECLARE_PRINTER(JSProxy)
DECLARE_VERIFIER(JSProxy)
// Layout description. We add padding so that a proxy has the same
@@ -8135,12 +8376,7 @@ class JSFunctionProxy: public JSProxy {
static inline JSFunctionProxy* cast(Object* obj);
// Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void JSFunctionProxyPrint() {
- JSFunctionProxyPrint(stdout);
- }
- void JSFunctionProxyPrint(FILE* out);
-#endif
+ DECLARE_PRINTER(JSFunctionProxy)
DECLARE_VERIFIER(JSFunctionProxy)
// Layout description.
@@ -8170,12 +8406,8 @@ class JSSet: public JSObject {
// Casting.
static inline JSSet* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void JSSetPrint() {
- JSSetPrint(stdout);
- }
- void JSSetPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(JSSet)
DECLARE_VERIFIER(JSSet)
static const int kTableOffset = JSObject::kHeaderSize;
@@ -8195,12 +8427,8 @@ class JSMap: public JSObject {
// Casting.
static inline JSMap* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void JSMapPrint() {
- JSMapPrint(stdout);
- }
- void JSMapPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(JSMap)
DECLARE_VERIFIER(JSMap)
static const int kTableOffset = JSObject::kHeaderSize;
@@ -8223,12 +8451,8 @@ class JSWeakMap: public JSObject {
// Casting.
static inline JSWeakMap* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void JSWeakMapPrint() {
- JSWeakMapPrint(stdout);
- }
- void JSWeakMapPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(JSWeakMap)
DECLARE_VERIFIER(JSWeakMap)
static const int kTableOffset = JSObject::kHeaderSize;
@@ -8258,12 +8482,8 @@ class Foreign: public HeapObject {
template<typename StaticVisitor>
inline void ForeignIterateBody();
-#ifdef OBJECT_PRINT
- inline void ForeignPrint() {
- ForeignPrint(stdout);
- }
- void ForeignPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(Foreign)
DECLARE_VERIFIER(Foreign)
// Layout description.
@@ -8298,10 +8518,11 @@ class JSArray: public JSObject {
// Initialize the array with the given capacity. The function may
// fail due to out-of-memory situations, but only if the requested
// capacity is non-zero.
- MUST_USE_RESULT MaybeObject* Initialize(int capacity);
+ MUST_USE_RESULT MaybeObject* Initialize(int capacity, int length = 0);
// 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.
@@ -8315,12 +8536,7 @@ class JSArray: public JSObject {
inline void EnsureSize(int minimum_size_of_backing_fixed_array);
// Dispatched behavior.
-#ifdef OBJECT_PRINT
- inline void JSArrayPrint() {
- JSArrayPrint(stdout);
- }
- void JSArrayPrint(FILE* out);
-#endif
+ DECLARE_PRINTER(JSArray)
DECLARE_VERIFIER(JSArray)
// Number of element slots to pre-allocate for an empty array.
@@ -8359,20 +8575,8 @@ class JSRegExpResult: public JSArray {
};
-// An accessor must have a getter, but can have no setter.
-//
-// When setting a property, V8 searches accessors in prototypes.
-// If an accessor was found and it does not have a setter,
-// the request is ignored.
-//
-// If the accessor in the prototype has the READ_ONLY property attribute, then
-// a new value is added to the local object when the property is set.
-// This shadows the accessor in the prototype.
class AccessorInfo: public Struct {
public:
- DECL_ACCESSORS(getter, Object)
- DECL_ACCESSORS(setter, Object)
- DECL_ACCESSORS(data, Object)
DECL_ACCESSORS(name, Object)
DECL_ACCESSORS(flag, Smi)
DECL_ACCESSORS(expected_receiver_type, Object)
@@ -8394,18 +8598,11 @@ class AccessorInfo: public Struct {
static inline AccessorInfo* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void AccessorInfoPrint() {
- AccessorInfoPrint(stdout);
- }
- void AccessorInfoPrint(FILE* out);
-#endif
+ // Dispatched behavior.
DECLARE_VERIFIER(AccessorInfo)
- static const int kGetterOffset = HeapObject::kHeaderSize;
- static const int kSetterOffset = kGetterOffset + kPointerSize;
- static const int kDataOffset = kSetterOffset + kPointerSize;
- static const int kNameOffset = kDataOffset + kPointerSize;
+
+ static const int kNameOffset = HeapObject::kHeaderSize;
static const int kFlagOffset = kNameOffset + kPointerSize;
static const int kExpectedReceiverTypeOffset = kFlagOffset + kPointerSize;
static const int kSize = kExpectedReceiverTypeOffset + kPointerSize;
@@ -8421,6 +8618,146 @@ class AccessorInfo: public Struct {
};
+enum AccessorDescriptorType {
+ kDescriptorBitmaskCompare,
+ kDescriptorPointerCompare,
+ kDescriptorPrimitiveValue,
+ kDescriptorObjectDereference,
+ kDescriptorPointerDereference,
+ kDescriptorPointerShift,
+ kDescriptorReturnObject
+};
+
+
+struct BitmaskCompareDescriptor {
+ uint32_t bitmask;
+ uint32_t compare_value;
+ uint8_t size; // Must be in {1,2,4}.
+};
+
+
+struct PointerCompareDescriptor {
+ void* compare_value;
+};
+
+
+struct PrimitiveValueDescriptor {
+ v8::DeclaredAccessorDescriptorDataType data_type;
+ uint8_t bool_offset; // Must be in [0,7], used for kDescriptorBoolType.
+};
+
+
+struct ObjectDerefenceDescriptor {
+ uint8_t internal_field;
+};
+
+
+struct PointerShiftDescriptor {
+ int16_t byte_offset;
+};
+
+
+struct DeclaredAccessorDescriptorData {
+ AccessorDescriptorType type;
+ union {
+ struct BitmaskCompareDescriptor bitmask_compare_descriptor;
+ struct PointerCompareDescriptor pointer_compare_descriptor;
+ struct PrimitiveValueDescriptor primitive_value_descriptor;
+ struct ObjectDerefenceDescriptor object_dereference_descriptor;
+ struct PointerShiftDescriptor pointer_shift_descriptor;
+ };
+};
+
+
+class DeclaredAccessorDescriptor;
+
+
+class DeclaredAccessorDescriptorIterator {
+ public:
+ explicit DeclaredAccessorDescriptorIterator(
+ DeclaredAccessorDescriptor* descriptor);
+ const DeclaredAccessorDescriptorData* Next();
+ bool Complete() const { return length_ == offset_; }
+ private:
+ uint8_t* array_;
+ const int length_;
+ int offset_;
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DeclaredAccessorDescriptorIterator);
+};
+
+
+class DeclaredAccessorDescriptor: public Struct {
+ public:
+ DECL_ACCESSORS(serialized_data, ByteArray)
+
+ static inline DeclaredAccessorDescriptor* cast(Object* obj);
+
+ static Handle<DeclaredAccessorDescriptor> Create(
+ Isolate* isolate,
+ const DeclaredAccessorDescriptorData& data,
+ Handle<DeclaredAccessorDescriptor> previous);
+
+ // Dispatched behavior.
+ DECLARE_PRINTER(DeclaredAccessorDescriptor)
+ DECLARE_VERIFIER(DeclaredAccessorDescriptor)
+
+ static const int kSerializedDataOffset = HeapObject::kHeaderSize;
+ static const int kSize = kSerializedDataOffset + kPointerSize;
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DeclaredAccessorDescriptor);
+};
+
+
+class DeclaredAccessorInfo: public AccessorInfo {
+ public:
+ DECL_ACCESSORS(descriptor, DeclaredAccessorDescriptor)
+
+ static inline DeclaredAccessorInfo* cast(Object* obj);
+
+ // Dispatched behavior.
+ DECLARE_PRINTER(DeclaredAccessorInfo)
+ DECLARE_VERIFIER(DeclaredAccessorInfo)
+
+ static const int kDescriptorOffset = AccessorInfo::kSize;
+ static const int kSize = kDescriptorOffset + kPointerSize;
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DeclaredAccessorInfo);
+};
+
+
+// An accessor must have a getter, but can have no setter.
+//
+// When setting a property, V8 searches accessors in prototypes.
+// If an accessor was found and it does not have a setter,
+// the request is ignored.
+//
+// If the accessor in the prototype has the READ_ONLY property attribute, then
+// a new value is added to the local object when the property is set.
+// This shadows the accessor in the prototype.
+class ExecutableAccessorInfo: public AccessorInfo {
+ public:
+ DECL_ACCESSORS(getter, Object)
+ DECL_ACCESSORS(setter, Object)
+ DECL_ACCESSORS(data, Object)
+
+ static inline ExecutableAccessorInfo* cast(Object* obj);
+
+ // Dispatched behavior.
+ DECLARE_PRINTER(ExecutableAccessorInfo)
+ DECLARE_VERIFIER(ExecutableAccessorInfo)
+
+ static const int kGetterOffset = AccessorInfo::kSize;
+ static const int kSetterOffset = kGetterOffset + kPointerSize;
+ static const int kDataOffset = kSetterOffset + kPointerSize;
+ static const int kSize = kDataOffset + kPointerSize;
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ExecutableAccessorInfo);
+};
+
+
// Support for JavaScript accessors: A pair of a getter and a setter. Each
// accessor can either be
// * a pointer to a JavaScript function or proxy: a real accessor
@@ -8461,9 +8798,8 @@ class AccessorPair: public Struct {
return IsJSAccessor(getter()) || IsJSAccessor(setter());
}
-#ifdef OBJECT_PRINT
- void AccessorPairPrint(FILE* out = stdout);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(AccessorPair)
DECLARE_VERIFIER(AccessorPair)
static const int kGetterOffset = HeapObject::kHeaderSize;
@@ -8492,12 +8828,8 @@ class AccessCheckInfo: public Struct {
static inline AccessCheckInfo* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void AccessCheckInfoPrint() {
- AccessCheckInfoPrint(stdout);
- }
- void AccessCheckInfoPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(AccessCheckInfo)
DECLARE_VERIFIER(AccessCheckInfo)
static const int kNamedCallbackOffset = HeapObject::kHeaderSize;
@@ -8521,12 +8853,8 @@ class InterceptorInfo: public Struct {
static inline InterceptorInfo* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void InterceptorInfoPrint() {
- InterceptorInfoPrint(stdout);
- }
- void InterceptorInfoPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(InterceptorInfo)
DECLARE_VERIFIER(InterceptorInfo)
static const int kGetterOffset = HeapObject::kHeaderSize;
@@ -8549,12 +8877,8 @@ class CallHandlerInfo: public Struct {
static inline CallHandlerInfo* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void CallHandlerInfoPrint() {
- CallHandlerInfoPrint(stdout);
- }
- void CallHandlerInfoPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(CallHandlerInfo)
DECLARE_VERIFIER(CallHandlerInfo)
static const int kCallbackOffset = HeapObject::kHeaderSize;
@@ -8598,6 +8922,9 @@ class FunctionTemplateInfo: public TemplateInfo {
DECL_ACCESSORS(access_check_info, Object)
DECL_ACCESSORS(flag, Smi)
+ inline int length();
+ inline void set_length(int value);
+
// Following properties use flag bits.
DECL_BOOLEAN_ACCESSORS(hidden_prototype)
DECL_BOOLEAN_ACCESSORS(undetectable)
@@ -8608,12 +8935,8 @@ class FunctionTemplateInfo: public TemplateInfo {
static inline FunctionTemplateInfo* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void FunctionTemplateInfoPrint() {
- FunctionTemplateInfoPrint(stdout);
- }
- void FunctionTemplateInfoPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(FunctionTemplateInfo)
DECLARE_VERIFIER(FunctionTemplateInfo)
static const int kSerialNumberOffset = TemplateInfo::kHeaderSize;
@@ -8635,7 +8958,8 @@ class FunctionTemplateInfo: public TemplateInfo {
static const int kAccessCheckInfoOffset =
kInstanceCallHandlerOffset + kPointerSize;
static const int kFlagOffset = kAccessCheckInfoOffset + kPointerSize;
- static const int kSize = kFlagOffset + kPointerSize;
+ static const int kLengthOffset = kFlagOffset + kPointerSize;
+ static const int kSize = kLengthOffset + kPointerSize;
private:
// Bit position in the flag, from least significant bit position.
@@ -8655,12 +8979,8 @@ class ObjectTemplateInfo: public TemplateInfo {
static inline ObjectTemplateInfo* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void ObjectTemplateInfoPrint() {
- ObjectTemplateInfoPrint(stdout);
- }
- void ObjectTemplateInfoPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(ObjectTemplateInfo)
DECLARE_VERIFIER(ObjectTemplateInfo)
static const int kConstructorOffset = TemplateInfo::kHeaderSize;
@@ -8677,12 +8997,8 @@ class SignatureInfo: public Struct {
static inline SignatureInfo* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void SignatureInfoPrint() {
- SignatureInfoPrint(stdout);
- }
- void SignatureInfoPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(SignatureInfo)
DECLARE_VERIFIER(SignatureInfo)
static const int kReceiverOffset = Struct::kHeaderSize;
@@ -8700,12 +9016,8 @@ class TypeSwitchInfo: public Struct {
static inline TypeSwitchInfo* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void TypeSwitchInfoPrint() {
- TypeSwitchInfoPrint(stdout);
- }
- void TypeSwitchInfoPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(TypeSwitchInfo)
DECLARE_VERIFIER(TypeSwitchInfo)
static const int kTypesOffset = Struct::kHeaderSize;
@@ -8750,12 +9062,8 @@ class DebugInfo: public Struct {
static inline DebugInfo* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void DebugInfoPrint() {
- DebugInfoPrint(stdout);
- }
- void DebugInfoPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(DebugInfo)
DECLARE_VERIFIER(DebugInfo)
static const int kSharedFunctionInfoIndex = Struct::kHeaderSize;
@@ -8806,12 +9114,8 @@ class BreakPointInfo: public Struct {
static inline BreakPointInfo* cast(Object* obj);
-#ifdef OBJECT_PRINT
- inline void BreakPointInfoPrint() {
- BreakPointInfoPrint(stdout);
- }
- void BreakPointInfoPrint(FILE* out);
-#endif
+ // Dispatched behavior.
+ DECLARE_PRINTER(BreakPointInfo)
DECLARE_VERIFIER(BreakPointInfo)
static const int kCodePositionIndex = Struct::kHeaderSize;
@@ -8833,10 +9137,10 @@ class BreakPointInfo: public Struct {
#undef DECLARE_VERIFIER
#define VISITOR_SYNCHRONIZATION_TAGS_LIST(V) \
- V(kSymbolTable, "symbol_table", "(Symbols)") \
+ V(kStringTable, "string_table", "(Internalized strings)") \
V(kExternalStringsTable, "external_strings_table", "(External strings)") \
V(kStrongRootList, "strong_root_list", "(Strong roots)") \
- V(kSymbol, "symbol", "(Symbol)") \
+ V(kInternalizedString, "internalized_string", "(Internal string)") \
V(kBootstrapper, "bootstrapper", "(Bootstrapper)") \
V(kTop, "top", "(Isolate)") \
V(kRelocatable, "relocatable", "(Relocatable)") \
@@ -8895,6 +9199,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); }