summaryrefslogtreecommitdiffstats
path: root/chromium/v8/src/objects.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/objects.h')
-rw-r--r--chromium/v8/src/objects.h4437
1 files changed, 2530 insertions, 1907 deletions
diff --git a/chromium/v8/src/objects.h b/chromium/v8/src/objects.h
index a7f01d18569..73566d885e3 100644
--- a/chromium/v8/src/objects.h
+++ b/chromium/v8/src/objects.h
@@ -1,160 +1,142 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_OBJECTS_H_
#define V8_OBJECTS_H_
-#include "allocation.h"
-#include "assert-scope.h"
-#include "builtins.h"
-#include "elements-kind.h"
-#include "flags.h"
-#include "list.h"
-#include "property-details.h"
-#include "smart-pointers.h"
-#include "unicode-inl.h"
-#if V8_TARGET_ARCH_ARM
-#include "arm/constants-arm.h"
+#include "src/allocation.h"
+#include "src/assert-scope.h"
+#include "src/builtins.h"
+#include "src/elements-kind.h"
+#include "src/field-index.h"
+#include "src/flags.h"
+#include "src/list.h"
+#include "src/property-details.h"
+#include "src/smart-pointers.h"
+#include "src/unicode-inl.h"
+#if V8_TARGET_ARCH_ARM64
+#include "src/arm64/constants-arm64.h"
+#elif V8_TARGET_ARCH_ARM
+#include "src/arm/constants-arm.h"
#elif V8_TARGET_ARCH_MIPS
-#include "mips/constants-mips.h"
+#include "src/mips/constants-mips.h"
#endif
-#include "v8checks.h"
-#include "zone.h"
+#include "src/v8checks.h"
+#include "src/zone.h"
//
// Most object types in the V8 JavaScript are described in this file.
//
// Inheritance hierarchy:
-// - MaybeObject (an object or a failure)
-// - Failure (immediate for marking failed operation)
-// - Object
-// - Smi (immediate small integer)
-// - HeapObject (superclass for everything allocated in the heap)
-// - JSReceiver (suitable for property access)
-// - JSObject
-// - JSArray
-// - JSArrayBuffer
-// - JSArrayBufferView
-// - JSTypedArray
-// - JSDataView
-// - JSSet
-// - JSMap
-// - JSWeakCollection
-// - JSWeakMap
-// - JSWeakSet
-// - JSRegExp
-// - JSFunction
-// - JSGeneratorObject
-// - JSModule
-// - GlobalObject
-// - JSGlobalObject
-// - JSBuiltinsObject
-// - JSGlobalProxy
-// - JSValue
-// - JSDate
-// - JSMessageObject
-// - JSProxy
-// - JSFunctionProxy
-// - FixedArrayBase
-// - ByteArray
-// - FixedArray
-// - DescriptorArray
-// - HashTable
-// - Dictionary
-// - StringTable
-// - CompilationCacheTable
-// - CodeCacheHashTable
-// - MapCache
-// - Context
-// - JSFunctionResultCache
-// - ScopeInfo
-// - TransitionArray
-// - FixedDoubleArray
-// - ExternalArray
-// - ExternalPixelArray
-// - ExternalByteArray
-// - ExternalUnsignedByteArray
-// - ExternalShortArray
-// - ExternalUnsignedShortArray
-// - ExternalIntArray
-// - ExternalUnsignedIntArray
-// - ExternalFloatArray
-// - Name
-// - String
-// - SeqString
-// - SeqOneByteString
-// - SeqTwoByteString
-// - SlicedString
-// - ConsString
-// - ExternalString
-// - ExternalAsciiString
-// - ExternalTwoByteString
-// - InternalizedString
-// - SeqInternalizedString
-// - SeqOneByteInternalizedString
-// - SeqTwoByteInternalizedString
-// - ConsInternalizedString
-// - ExternalInternalizedString
-// - ExternalAsciiInternalizedString
-// - ExternalTwoByteInternalizedString
-// - Symbol
-// - HeapNumber
-// - Cell
-// - PropertyCell
-// - Code
-// - Map
-// - Oddball
-// - Foreign
-// - SharedFunctionInfo
-// - Struct
-// - Box
-// - DeclaredAccessorDescriptor
-// - AccessorInfo
-// - DeclaredAccessorInfo
-// - ExecutableAccessorInfo
-// - AccessorPair
-// - AccessCheckInfo
-// - InterceptorInfo
-// - CallHandlerInfo
-// - TemplateInfo
-// - FunctionTemplateInfo
-// - ObjectTemplateInfo
-// - Script
-// - SignatureInfo
-// - TypeSwitchInfo
-// - DebugInfo
-// - BreakPointInfo
-// - CodeCache
+// - Object
+// - Smi (immediate small integer)
+// - HeapObject (superclass for everything allocated in the heap)
+// - JSReceiver (suitable for property access)
+// - JSObject
+// - JSArray
+// - JSArrayBuffer
+// - JSArrayBufferView
+// - JSTypedArray
+// - JSDataView
+// - JSSet
+// - JSMap
+// - JSSetIterator
+// - JSMapIterator
+// - JSWeakCollection
+// - JSWeakMap
+// - JSWeakSet
+// - JSRegExp
+// - JSFunction
+// - JSGeneratorObject
+// - JSModule
+// - GlobalObject
+// - JSGlobalObject
+// - JSBuiltinsObject
+// - JSGlobalProxy
+// - JSValue
+// - JSDate
+// - JSMessageObject
+// - JSProxy
+// - JSFunctionProxy
+// - FixedArrayBase
+// - ByteArray
+// - FixedArray
+// - DescriptorArray
+// - HashTable
+// - Dictionary
+// - StringTable
+// - CompilationCacheTable
+// - CodeCacheHashTable
+// - MapCache
+// - OrderedHashTable
+// - OrderedHashSet
+// - OrderedHashMap
+// - Context
+// - JSFunctionResultCache
+// - ScopeInfo
+// - TransitionArray
+// - FixedDoubleArray
+// - ExternalArray
+// - ExternalUint8ClampedArray
+// - ExternalInt8Array
+// - ExternalUint8Array
+// - ExternalInt16Array
+// - ExternalUint16Array
+// - ExternalInt32Array
+// - ExternalUint32Array
+// - ExternalFloat32Array
+// - Name
+// - String
+// - SeqString
+// - SeqOneByteString
+// - SeqTwoByteString
+// - SlicedString
+// - ConsString
+// - ExternalString
+// - ExternalAsciiString
+// - ExternalTwoByteString
+// - InternalizedString
+// - SeqInternalizedString
+// - SeqOneByteInternalizedString
+// - SeqTwoByteInternalizedString
+// - ConsInternalizedString
+// - ExternalInternalizedString
+// - ExternalAsciiInternalizedString
+// - ExternalTwoByteInternalizedString
+// - Symbol
+// - HeapNumber
+// - Cell
+// - PropertyCell
+// - Code
+// - Map
+// - Oddball
+// - Foreign
+// - SharedFunctionInfo
+// - Struct
+// - Box
+// - DeclaredAccessorDescriptor
+// - AccessorInfo
+// - DeclaredAccessorInfo
+// - ExecutableAccessorInfo
+// - AccessorPair
+// - AccessCheckInfo
+// - InterceptorInfo
+// - CallHandlerInfo
+// - TemplateInfo
+// - FunctionTemplateInfo
+// - ObjectTemplateInfo
+// - Script
+// - SignatureInfo
+// - TypeSwitchInfo
+// - DebugInfo
+// - BreakPointInfo
+// - CodeCache
//
// Formats of Object*:
// Smi: [31 bit signed int] 0
// HeapObject: [32 bit direct pointer] (4 byte aligned) | 01
-// Failure: [30 bit signed int] 11
namespace v8 {
namespace internal {
@@ -353,8 +335,6 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
\
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_ONE_BYTE_DATA_TYPE) \
@@ -377,15 +357,26 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
/* Note: the order of these external array */ \
/* types is relied upon in */ \
/* Object::IsExternalArray(). */ \
- V(EXTERNAL_BYTE_ARRAY_TYPE) \
- V(EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE) \
- V(EXTERNAL_SHORT_ARRAY_TYPE) \
- V(EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE) \
- V(EXTERNAL_INT_ARRAY_TYPE) \
- V(EXTERNAL_UNSIGNED_INT_ARRAY_TYPE) \
- V(EXTERNAL_FLOAT_ARRAY_TYPE) \
- V(EXTERNAL_DOUBLE_ARRAY_TYPE) \
- V(EXTERNAL_PIXEL_ARRAY_TYPE) \
+ V(EXTERNAL_INT8_ARRAY_TYPE) \
+ V(EXTERNAL_UINT8_ARRAY_TYPE) \
+ V(EXTERNAL_INT16_ARRAY_TYPE) \
+ V(EXTERNAL_UINT16_ARRAY_TYPE) \
+ V(EXTERNAL_INT32_ARRAY_TYPE) \
+ V(EXTERNAL_UINT32_ARRAY_TYPE) \
+ V(EXTERNAL_FLOAT32_ARRAY_TYPE) \
+ V(EXTERNAL_FLOAT64_ARRAY_TYPE) \
+ V(EXTERNAL_UINT8_CLAMPED_ARRAY_TYPE) \
+ \
+ V(FIXED_INT8_ARRAY_TYPE) \
+ V(FIXED_UINT8_ARRAY_TYPE) \
+ V(FIXED_INT16_ARRAY_TYPE) \
+ V(FIXED_UINT16_ARRAY_TYPE) \
+ V(FIXED_INT32_ARRAY_TYPE) \
+ V(FIXED_UINT32_ARRAY_TYPE) \
+ V(FIXED_FLOAT32_ARRAY_TYPE) \
+ V(FIXED_FLOAT64_ARRAY_TYPE) \
+ V(FIXED_UINT8_CLAMPED_ARRAY_TYPE) \
+ \
V(FILLER_TYPE) \
\
V(DECLARED_ACCESSOR_DESCRIPTOR_TYPE) \
@@ -431,6 +422,8 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
V(JS_PROXY_TYPE) \
V(JS_SET_TYPE) \
V(JS_MAP_TYPE) \
+ V(JS_SET_ITERATOR_TYPE) \
+ V(JS_MAP_ITERATOR_TYPE) \
V(JS_WEAK_MAP_TYPE) \
V(JS_WEAK_SET_TYPE) \
V(JS_REGEXP_TYPE) \
@@ -478,7 +471,7 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
ExternalAsciiString) \
V(EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE, \
ExternalTwoByteString::kSize, \
- external_string_with_one_bytei_data, \
+ external_string_with_one_byte_data, \
ExternalStringWithOneByteData) \
V(SHORT_EXTERNAL_STRING_TYPE, \
ExternalTwoByteString::kShortSize, \
@@ -501,14 +494,6 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
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, \
@@ -543,7 +528,7 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
// Note that for subtle reasons related to the ordering or numerical values of
// type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST
// manually.
-#define STRUCT_LIST_ALL(V) \
+#define STRUCT_LIST(V) \
V(BOX, Box, box) \
V(DECLARED_ACCESSOR_DESCRIPTOR, \
DeclaredAccessorDescriptor, \
@@ -564,19 +549,9 @@ const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
V(CODE_CACHE, CodeCache, code_cache) \
V(POLYMORPHIC_CODE_CACHE, PolymorphicCodeCache, polymorphic_code_cache) \
V(TYPE_FEEDBACK_INFO, TypeFeedbackInfo, type_feedback_info) \
- V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry)
-
-#ifdef ENABLE_DEBUGGER_SUPPORT
-#define STRUCT_LIST_DEBUGGER(V) \
+ V(ALIASED_ARGUMENTS_ENTRY, AliasedArgumentsEntry, aliased_arguments_entry) \
V(DEBUG_INFO, DebugInfo, debug_info) \
V(BREAK_POINT_INFO, BreakPointInfo, break_point_info)
-#else
-#define STRUCT_LIST_DEBUGGER(V)
-#endif
-
-#define STRUCT_LIST(V) \
- STRUCT_LIST_ALL(V) \
- STRUCT_LIST_DEBUGGER(V)
// We use the full 8 bits of the instance_type field to encode heap object
// instance types. The high-order bit (bit 7) is set if the object is not a
@@ -608,17 +583,17 @@ enum StringRepresentationTag {
};
const uint32_t kIsIndirectStringMask = 0x1;
const uint32_t kIsIndirectStringTag = 0x1;
-STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0);
-STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0);
-STATIC_ASSERT(
- (kConsStringTag & kIsIndirectStringMask) == kIsIndirectStringTag);
-STATIC_ASSERT(
- (kSlicedStringTag & kIsIndirectStringMask) == kIsIndirectStringTag);
+STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0); // NOLINT
+STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0); // NOLINT
+STATIC_ASSERT((kConsStringTag &
+ kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
+STATIC_ASSERT((kSlicedStringTag &
+ kIsIndirectStringMask) == kIsIndirectStringTag); // NOLINT
// Use this mask to distinguish between cons and slice only after making
// sure that the string is one of the two (an indirect string).
const uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag;
-STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask) && kSlicedNotConsMask != 0);
+STATIC_ASSERT(IS_POWER_OF_TWO(kSlicedNotConsMask));
// If bit 7 is clear, then bit 3 indicates whether this two-byte
// string actually contains one byte data.
@@ -649,10 +624,6 @@ enum InstanceType {
| kInternalizedTag,
ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag | kSeqStringTag
| kInternalizedTag,
- CONS_INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kConsStringTag
- | kInternalizedTag,
- CONS_ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag | kConsStringTag
- | kInternalizedTag,
EXTERNAL_INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kExternalStringTag
| kInternalizedTag,
EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE = kOneByteStringTag
@@ -672,9 +643,9 @@ enum InstanceType {
STRING_TYPE = INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
ASCII_STRING_TYPE = ASCII_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
- CONS_STRING_TYPE = CONS_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
+ CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag | kNotInternalizedTag,
CONS_ASCII_STRING_TYPE =
- CONS_ASCII_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
+ kOneByteStringTag | kConsStringTag | kNotInternalizedTag,
SLICED_STRING_TYPE =
kTwoByteStringTag | kSlicedStringTag | kNotInternalizedTag,
@@ -711,17 +682,28 @@ enum InstanceType {
FOREIGN_TYPE,
BYTE_ARRAY_TYPE,
FREE_SPACE_TYPE,
- EXTERNAL_BYTE_ARRAY_TYPE, // FIRST_EXTERNAL_ARRAY_TYPE
- EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE,
- EXTERNAL_SHORT_ARRAY_TYPE,
- EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE,
- EXTERNAL_INT_ARRAY_TYPE,
- EXTERNAL_UNSIGNED_INT_ARRAY_TYPE,
- EXTERNAL_FLOAT_ARRAY_TYPE,
- EXTERNAL_DOUBLE_ARRAY_TYPE,
- EXTERNAL_PIXEL_ARRAY_TYPE, // LAST_EXTERNAL_ARRAY_TYPE
+
+ EXTERNAL_INT8_ARRAY_TYPE, // FIRST_EXTERNAL_ARRAY_TYPE
+ EXTERNAL_UINT8_ARRAY_TYPE,
+ EXTERNAL_INT16_ARRAY_TYPE,
+ EXTERNAL_UINT16_ARRAY_TYPE,
+ EXTERNAL_INT32_ARRAY_TYPE,
+ EXTERNAL_UINT32_ARRAY_TYPE,
+ EXTERNAL_FLOAT32_ARRAY_TYPE,
+ EXTERNAL_FLOAT64_ARRAY_TYPE,
+ EXTERNAL_UINT8_CLAMPED_ARRAY_TYPE, // LAST_EXTERNAL_ARRAY_TYPE
+
+ FIXED_INT8_ARRAY_TYPE, // FIRST_FIXED_TYPED_ARRAY_TYPE
+ FIXED_UINT8_ARRAY_TYPE,
+ FIXED_INT16_ARRAY_TYPE,
+ FIXED_UINT16_ARRAY_TYPE,
+ FIXED_INT32_ARRAY_TYPE,
+ FIXED_UINT32_ARRAY_TYPE,
+ FIXED_FLOAT32_ARRAY_TYPE,
+ FIXED_FLOAT64_ARRAY_TYPE,
+ FIXED_UINT8_CLAMPED_ARRAY_TYPE, // LAST_FIXED_TYPED_ARRAY_TYPE
+
FIXED_DOUBLE_ARRAY_TYPE,
- CONSTANT_POOL_ARRAY_TYPE,
FILLER_TYPE, // LAST_DATA_TYPE
// Structs.
@@ -744,18 +726,13 @@ enum InstanceType {
TYPE_FEEDBACK_INFO_TYPE,
ALIASED_ARGUMENTS_ENTRY_TYPE,
BOX_TYPE,
- // The following two instance types are only used when ENABLE_DEBUGGER_SUPPORT
- // is defined. However as include/v8.h contain some of the instance type
- // constants always having them avoids them getting different numbers
- // depending on whether ENABLE_DEBUGGER_SUPPORT is defined or not.
DEBUG_INFO_TYPE,
BREAK_POINT_INFO_TYPE,
FIXED_ARRAY_TYPE,
+ CONSTANT_POOL_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
- JS_MESSAGE_OBJECT_TYPE,
-
// All the following types are subtypes of JSReceiver, which corresponds to
// objects in the JS sense. The first and the last type in this range are
// the two forms of function. This organization enables using the same
@@ -765,6 +742,7 @@ enum InstanceType {
JS_PROXY_TYPE, // LAST_JS_PROXY_TYPE
JS_VALUE_TYPE, // FIRST_JS_OBJECT_TYPE
+ JS_MESSAGE_OBJECT_TYPE,
JS_DATE_TYPE,
JS_OBJECT_TYPE,
JS_CONTEXT_EXTENSION_OBJECT_TYPE,
@@ -779,6 +757,8 @@ enum InstanceType {
JS_DATA_VIEW_TYPE,
JS_SET_TYPE,
JS_MAP_TYPE,
+ JS_SET_ITERATOR_TYPE,
+ JS_MAP_ITERATOR_TYPE,
JS_WEAK_MAP_TYPE,
JS_WEAK_SET_TYPE,
@@ -795,8 +775,11 @@ enum InstanceType {
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,
+ FIRST_EXTERNAL_ARRAY_TYPE = EXTERNAL_INT8_ARRAY_TYPE,
+ LAST_EXTERNAL_ARRAY_TYPE = EXTERNAL_UINT8_CLAMPED_ARRAY_TYPE,
+ // Boundaries for testing for a fixed typed array.
+ FIRST_FIXED_TYPED_ARRAY_TYPE = FIXED_INT8_ARRAY_TYPE,
+ LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_UINT8_CLAMPED_ARRAY_TYPE,
// Boundary for promotion to old data space/old pointer space.
LAST_DATA_TYPE = FILLER_TYPE,
// Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
@@ -826,10 +809,10 @@ enum InstanceType {
const int kExternalArrayTypeCount =
LAST_EXTERNAL_ARRAY_TYPE - FIRST_EXTERNAL_ARRAY_TYPE + 1;
-STATIC_CHECK(JS_OBJECT_TYPE == Internals::kJSObjectType);
-STATIC_CHECK(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
-STATIC_CHECK(ODDBALL_TYPE == Internals::kOddballType);
-STATIC_CHECK(FOREIGN_TYPE == Internals::kForeignType);
+STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType);
+STATIC_ASSERT(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
+STATIC_ASSERT(ODDBALL_TYPE == Internals::kOddballType);
+STATIC_ASSERT(FOREIGN_TYPE == Internals::kForeignType);
#define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V) \
@@ -876,12 +859,15 @@ class AllocationSiteCreationContext;
class AllocationSiteUsageContext;
class DictionaryElementsAccessor;
class ElementsAccessor;
-class Failure;
class FixedArrayBase;
class GlobalObject;
class ObjectVisitor;
+class LookupIterator;
class StringStream;
-class Type;
+// We cannot just say "class HeapType;" if it is created from a template... =8-?
+template<class> class TypeImpl;
+struct HeapTypeConfig;
+typedef TypeImpl<HeapTypeConfig> HeapType;
// A template-ized version of the IsXXX functions.
@@ -899,61 +885,6 @@ template <class C> inline bool Is(Object* obj);
#define DECLARE_PRINTER(Name)
#endif
-class MaybeObject BASE_EMBEDDED {
- public:
- inline bool IsFailure();
- inline bool IsRetryAfterGC();
- inline bool IsOutOfMemory();
- inline bool IsException();
- INLINE(bool IsTheHole());
- INLINE(bool IsUninitialized());
- inline bool ToObject(Object** obj) {
- if (IsFailure()) return false;
- *obj = reinterpret_cast<Object*>(this);
- return true;
- }
- inline Failure* ToFailureUnchecked() {
- ASSERT(IsFailure());
- return reinterpret_cast<Failure*>(this);
- }
- inline Object* ToObjectUnchecked() {
- // 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() {
- CHECK(!IsFailure());
- return reinterpret_cast<Object*>(this);
- }
-
- template<typename T>
- inline bool To(T** obj) {
- if (IsFailure()) return false;
- *obj = T::cast(reinterpret_cast<Object*>(this));
- 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.
- void Print();
- void Print(FILE* out);
- void PrintLn();
- void PrintLn(FILE* out);
-#endif
-#ifdef VERIFY_HEAP
- // Verifies the object.
- void Verify();
-#endif
-};
-
#define OBJECT_TYPE_LIST(V) \
V(Smi) \
@@ -977,15 +908,25 @@ class MaybeObject BASE_EMBEDDED {
V(Symbol) \
\
V(ExternalArray) \
- V(ExternalByteArray) \
- V(ExternalUnsignedByteArray) \
- V(ExternalShortArray) \
- V(ExternalUnsignedShortArray) \
- V(ExternalIntArray) \
- V(ExternalUnsignedIntArray) \
- V(ExternalFloatArray) \
- V(ExternalDoubleArray) \
- V(ExternalPixelArray) \
+ V(ExternalInt8Array) \
+ V(ExternalUint8Array) \
+ V(ExternalInt16Array) \
+ V(ExternalUint16Array) \
+ V(ExternalInt32Array) \
+ V(ExternalUint32Array) \
+ V(ExternalFloat32Array) \
+ V(ExternalFloat64Array) \
+ V(ExternalUint8ClampedArray) \
+ V(FixedTypedArrayBase) \
+ V(FixedUint8Array) \
+ V(FixedInt8Array) \
+ V(FixedUint16Array) \
+ V(FixedInt16Array) \
+ V(FixedUint32Array) \
+ V(FixedInt32Array) \
+ V(FixedFloat32Array) \
+ V(FixedFloat64Array) \
+ V(FixedUint8ClampedArray) \
V(ByteArray) \
V(FreeSpace) \
V(JSReceiver) \
@@ -999,7 +940,6 @@ class MaybeObject BASE_EMBEDDED {
V(DeoptimizationInputData) \
V(DeoptimizationOutputData) \
V(DependentCode) \
- V(TypeFeedbackCells) \
V(FixedArray) \
V(FixedDoubleArray) \
V(ConstantPoolArray) \
@@ -1025,6 +965,8 @@ class MaybeObject BASE_EMBEDDED {
V(JSFunctionProxy) \
V(JSSet) \
V(JSMap) \
+ V(JSSetIterator) \
+ V(JSMapIterator) \
V(JSWeakCollection) \
V(JSWeakMap) \
V(JSWeakSet) \
@@ -1048,7 +990,8 @@ class MaybeObject BASE_EMBEDDED {
V(Cell) \
V(PropertyCell) \
V(ObjectHashTable) \
- V(WeakHashTable)
+ V(WeakHashTable) \
+ V(OrderedHashTable)
#define ERROR_MESSAGES_LIST(V) \
@@ -1056,110 +999,129 @@ class MaybeObject BASE_EMBEDDED {
\
V(k32BitValueInRegisterIsNotZeroExtended, \
"32 bit value in register is not zero-extended") \
- V(kAlignmentMarkerExpected, "alignment marker expected") \
+ V(kAlignmentMarkerExpected, "Alignment marker expected") \
V(kAllocationIsNotDoubleAligned, "Allocation is not double aligned") \
V(kAPICallReturnedInvalidObject, "API call returned invalid object") \
V(kArgumentsObjectValueInATestContext, \
- "arguments object value in a test context") \
- V(kArrayBoilerplateCreationFailed, "array boilerplate creation failed") \
- V(kArrayIndexConstantValueTooBig, "array index constant value too big") \
- V(kAssignmentToArguments, "assignment to arguments") \
+ "Arguments object value in a test context") \
+ V(kArrayBoilerplateCreationFailed, "Array boilerplate creation failed") \
+ V(kArrayIndexConstantValueTooBig, "Array index constant value too big") \
+ V(kAssignmentToArguments, "Assignment to arguments") \
V(kAssignmentToLetVariableBeforeInitialization, \
- "assignment to let variable before initialization") \
- V(kAssignmentToLOOKUPVariable, "assignment to LOOKUP variable") \
+ "Assignment to let variable before initialization") \
+ V(kAssignmentToLOOKUPVariable, "Assignment to LOOKUP variable") \
V(kAssignmentToParameterFunctionUsesArgumentsObject, \
- "assignment to parameter, function uses arguments object") \
+ "Assignment to parameter, function uses arguments object") \
V(kAssignmentToParameterInArgumentsObject, \
- "assignment to parameter in arguments object") \
+ "Assignment to parameter in arguments object") \
V(kAttemptToUseUndefinedCache, "Attempt to use undefined cache") \
V(kBadValueContextForArgumentsObjectValue, \
- "bad value context for arguments object value") \
+ "Bad value context for arguments object value") \
V(kBadValueContextForArgumentsValue, \
- "bad value context for arguments value") \
- V(kBailedOutDueToDependencyChange, "bailed out due to dependency change") \
- V(kBailoutWasNotPrepared, "bailout was not prepared") \
+ "Bad value context for arguments value") \
+ V(kBailedOutDueToDependencyChange, "Bailed out due to dependency change") \
+ V(kBailoutWasNotPrepared, "Bailout was not prepared") \
V(kBinaryStubGenerateFloatingPointCode, \
"BinaryStub_GenerateFloatingPointCode") \
V(kBothRegistersWereSmisInSelectNonSmi, \
"Both registers were smis in SelectNonSmi") \
V(kCallToAJavaScriptRuntimeFunction, \
- "call to a JavaScript runtime function") \
+ "Call to a JavaScript runtime function") \
V(kCannotTranslatePositionInChangedArea, \
"Cannot translate position in changed area") \
- V(kCodeGenerationFailed, "code generation failed") \
- V(kCodeObjectNotProperlyPatched, "code object not properly patched") \
- V(kCompoundAssignmentToLookupSlot, "compound assignment to lookup slot") \
- V(kContextAllocatedArguments, "context-allocated arguments") \
- V(kDebuggerIsActive, "debugger is active") \
+ V(kCodeGenerationFailed, "Code generation failed") \
+ V(kCodeObjectNotProperlyPatched, "Code object not properly patched") \
+ V(kCompoundAssignmentToLookupSlot, "Compound assignment to lookup slot") \
+ V(kContextAllocatedArguments, "Context-allocated arguments") \
+ V(kCopyBuffersOverlap, "Copy buffers overlap") \
+ V(kCouldNotGenerateZero, "Could not generate +0.0") \
+ V(kCouldNotGenerateNegativeZero, "Could not generate -0.0") \
+ V(kDebuggerHasBreakPoints, "Debugger has break points") \
V(kDebuggerStatement, "DebuggerStatement") \
V(kDeclarationInCatchContext, "Declaration in catch context") \
V(kDeclarationInWithContext, "Declaration in with context") \
V(kDefaultNaNModeNotSet, "Default NaN mode not set") \
- V(kDeleteWithGlobalVariable, "delete with global variable") \
- V(kDeleteWithNonGlobalVariable, "delete with non-global variable") \
+ V(kDeleteWithGlobalVariable, "Delete with global variable") \
+ V(kDeleteWithNonGlobalVariable, "Delete with non-global variable") \
V(kDestinationOfCopyNotAligned, "Destination of copy not aligned") \
V(kDontDeleteCellsCannotContainTheHole, \
"DontDelete cells can't contain the hole") \
V(kDoPushArgumentNotImplementedForDoubleType, \
"DoPushArgument not implemented for double type") \
+ V(kEliminatedBoundsCheckFailed, "Eliminated bounds check failed") \
V(kEmitLoadRegisterUnsupportedDoubleImmediate, \
"EmitLoadRegister: Unsupported double immediate") \
V(kEval, "eval") \
V(kExpected0AsASmiSentinel, "Expected 0 as a Smi sentinel") \
- V(kExpectedAlignmentMarker, "expected alignment marker") \
+ V(kExpectedAlignmentMarker, "Expected alignment marker") \
+ V(kExpectedAllocationSite, "Expected allocation site") \
+ V(kExpectedFunctionObject, "Expected function object in register") \
+ V(kExpectedHeapNumber, "Expected HeapNumber") \
+ V(kExpectedNativeContext, "Expected native context") \
+ V(kExpectedNonIdenticalObjects, "Expected non-identical objects") \
+ V(kExpectedNonNullContext, "Expected non-null context") \
+ V(kExpectedPositiveZero, "Expected +0.0") \
V(kExpectedAllocationSiteInCell, \
"Expected AllocationSite in property cell") \
- V(kExpectedPropertyCellInRegisterA2, \
- "Expected property cell in register a2") \
- V(kExpectedPropertyCellInRegisterEbx, \
- "Expected property cell in register ebx") \
- V(kExpectedPropertyCellInRegisterRbx, \
- "Expected property cell in register rbx") \
+ V(kExpectedFixedArrayInFeedbackVector, \
+ "Expected fixed array in feedback vector") \
+ V(kExpectedFixedArrayInRegisterA2, \
+ "Expected fixed array in register a2") \
+ V(kExpectedFixedArrayInRegisterEbx, \
+ "Expected fixed array in register ebx") \
+ V(kExpectedFixedArrayInRegisterR2, \
+ "Expected fixed array in register r2") \
+ V(kExpectedFixedArrayInRegisterRbx, \
+ "Expected fixed array in register rbx") \
+ V(kExpectedNewSpaceObject, "Expected new space object") \
+ V(kExpectedSmiOrHeapNumber, "Expected smi or HeapNumber") \
+ V(kExpectedUndefinedOrCell, \
+ "Expected undefined or cell in register") \
V(kExpectingAlignmentForCopyBytes, \
"Expecting alignment for CopyBytes") \
V(kExportDeclaration, "Export declaration") \
V(kExternalStringExpectedButNotFound, \
- "external string expected, but not found") \
- V(kFailedBailedOutLastTime, "failed/bailed out last time") \
+ "External string expected, but not found") \
+ V(kFailedBailedOutLastTime, "Failed/bailed out last time") \
V(kForInStatementIsNotFastCase, "ForInStatement is not fast case") \
V(kForInStatementOptimizationIsDisabled, \
"ForInStatement optimization is disabled") \
V(kForInStatementWithNonLocalEachVariable, \
"ForInStatement with non-local each variable") \
V(kForOfStatement, "ForOfStatement") \
- V(kFrameIsExpectedToBeAligned, "frame is expected to be aligned") \
- V(kFunctionCallsEval, "function calls eval") \
- V(kFunctionIsAGenerator, "function is a generator") \
- V(kFunctionWithIllegalRedeclaration, "function with illegal redeclaration") \
+ V(kFrameIsExpectedToBeAligned, "Frame is expected to be aligned") \
+ V(kFunctionCallsEval, "Function calls eval") \
+ V(kFunctionIsAGenerator, "Function is a generator") \
+ V(kFunctionWithIllegalRedeclaration, "Function with illegal redeclaration") \
V(kGeneratedCodeIsTooLarge, "Generated code is too large") \
V(kGeneratorFailedToResume, "Generator failed to resume") \
- V(kGenerator, "generator") \
+ V(kGenerator, "Generator") \
V(kGlobalFunctionsMustHaveInitialMap, \
"Global functions must have initial map") \
V(kHeapNumberMapRegisterClobbered, "HeapNumberMap register clobbered") \
+ V(kHydrogenFilter, "Optimization disabled by filter") \
V(kImportDeclaration, "Import declaration") \
V(kImproperObjectOnPrototypeChainForStore, \
- "improper object on prototype chain for store") \
+ "Improper object on prototype chain for store") \
V(kIndexIsNegative, "Index is negative") \
V(kIndexIsTooLarge, "Index is too large") \
- V(kInlinedRuntimeFunctionClassOf, "inlined runtime function: ClassOf") \
+ V(kInlinedRuntimeFunctionClassOf, "Inlined runtime function: ClassOf") \
V(kInlinedRuntimeFunctionFastAsciiArrayJoin, \
- "inlined runtime function: FastAsciiArrayJoin") \
+ "Inlined runtime function: FastAsciiArrayJoin") \
V(kInlinedRuntimeFunctionGeneratorNext, \
- "inlined runtime function: GeneratorNext") \
+ "Inlined runtime function: GeneratorNext") \
V(kInlinedRuntimeFunctionGeneratorThrow, \
- "inlined runtime function: GeneratorThrow") \
+ "Inlined runtime function: GeneratorThrow") \
V(kInlinedRuntimeFunctionGetFromCache, \
- "inlined runtime function: GetFromCache") \
+ "Inlined runtime function: GetFromCache") \
V(kInlinedRuntimeFunctionIsNonNegativeSmi, \
- "inlined runtime function: IsNonNegativeSmi") \
- V(kInlinedRuntimeFunctionIsRegExpEquivalent, \
- "inlined runtime function: IsRegExpEquivalent") \
+ "Inlined runtime function: IsNonNegativeSmi") \
V(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf, \
- "inlined runtime function: IsStringWrapperSafeForDefaultValueOf") \
- V(kInliningBailedOut, "inlining bailed out") \
+ "Inlined runtime function: IsStringWrapperSafeForDefaultValueOf") \
+ V(kInliningBailedOut, "Inlining bailed out") \
V(kInputGPRIsExpectedToHaveUpper32Cleared, \
- "input GPR is expected to have upper32 cleared") \
+ "Input GPR is expected to have upper32 cleared") \
+ V(kInputStringTooLong, "Input string too long") \
V(kInstanceofStubUnexpectedCallSiteCacheCheck, \
"InstanceofStub unexpected call site cache (check)") \
V(kInstanceofStubUnexpectedCallSiteCacheCmp1, \
@@ -1173,10 +1135,11 @@ class MaybeObject BASE_EMBEDDED {
V(kInvalidCaptureReferenced, "Invalid capture referenced") \
V(kInvalidElementsKindForInternalArrayOrInternalPackedArray, \
"Invalid ElementsKind for InternalArray or InternalPackedArray") \
+ V(kInvalidFullCodegenState, "invalid full-codegen state") \
V(kInvalidHandleScopeLevel, "Invalid HandleScope level") \
- V(kInvalidLeftHandSideInAssignment, "invalid left-hand side in assignment") \
- V(kInvalidLhsInCompoundAssignment, "invalid lhs in compound assignment") \
- V(kInvalidLhsInCountOperation, "invalid lhs in count operation") \
+ V(kInvalidLeftHandSideInAssignment, "Invalid left-hand side in assignment") \
+ V(kInvalidLhsInCompoundAssignment, "Invalid lhs in compound assignment") \
+ V(kInvalidLhsInCountOperation, "Invalid lhs in count operation") \
V(kInvalidMinLength, "Invalid min_length") \
V(kJSGlobalObjectNativeContextShouldBeANativeContext, \
"JSGlobalObject::native_context should be a native context") \
@@ -1185,14 +1148,19 @@ class MaybeObject BASE_EMBEDDED {
V(kJSObjectWithFastElementsMapHasSlowElements, \
"JSObject with fast elements map has slow elements") \
V(kLetBindingReInitialization, "Let binding re-initialization") \
+ V(kLhsHasBeenClobbered, "lhs has been clobbered") \
V(kLiveBytesCountOverflowChunkSize, "Live Bytes Count overflow chunk size") \
+ V(kLiveEditFrameDroppingIsNotSupportedOnARM64, \
+ "LiveEdit frame dropping is not supported on arm64") \
V(kLiveEditFrameDroppingIsNotSupportedOnArm, \
"LiveEdit frame dropping is not supported on arm") \
V(kLiveEditFrameDroppingIsNotSupportedOnMips, \
"LiveEdit frame dropping is not supported on mips") \
V(kLiveEdit, "LiveEdit") \
V(kLookupVariableInCountOperation, \
- "lookup variable in count operation") \
+ "Lookup variable in count operation") \
+ V(kMapBecameDeprecated, "Map became deprecated") \
+ V(kMapBecameUnstable, "Map became unstable") \
V(kMapIsNoLongerInEax, "Map is no longer in eax") \
V(kModuleDeclaration, "Module declaration") \
V(kModuleLiteral, "Module literal") \
@@ -1201,26 +1169,28 @@ class MaybeObject BASE_EMBEDDED {
V(kModuleVariable, "Module variable") \
V(kModuleUrl, "Module url") \
V(kNativeFunctionLiteral, "Native function literal") \
- V(kNoCasesLeft, "no cases left") \
+ V(kNeedSmiLiteral, "Need a Smi literal here") \
+ V(kNoCasesLeft, "No cases left") \
V(kNoEmptyArraysHereInEmitFastAsciiArrayJoin, \
"No empty arrays here in EmitFastAsciiArrayJoin") \
V(kNonInitializerAssignmentToConst, \
- "non-initializer assignment to const") \
+ "Non-initializer assignment to const") \
V(kNonSmiIndex, "Non-smi index") \
V(kNonSmiKeyInArrayLiteral, "Non-smi key in array literal") \
V(kNonSmiValue, "Non-smi value") \
V(kNonObject, "Non-object value") \
V(kNotEnoughVirtualRegistersForValues, \
- "not enough virtual registers for values") \
+ "Not enough virtual registers for values") \
V(kNotEnoughSpillSlotsForOsr, \
- "not enough spill slots for OSR") \
+ "Not enough spill slots for OSR") \
V(kNotEnoughVirtualRegistersRegalloc, \
- "not enough virtual registers (regalloc)") \
- V(kObjectFoundInSmiOnlyArray, "object found in smi-only array") \
+ "Not enough virtual registers (regalloc)") \
+ V(kObjectFoundInSmiOnlyArray, "Object found in smi-only array") \
V(kObjectLiteralWithComplexProperty, \
"Object literal with complex property") \
V(kOddballInStringTableIsNotUndefinedOrTheHole, \
- "oddball in string table is not undefined or the hole") \
+ "Oddball in string table is not undefined or the hole") \
+ V(kOffsetOutOfRange, "Offset out of range") \
V(kOperandIsASmiAndNotAName, "Operand is a smi and not a name") \
V(kOperandIsASmiAndNotAString, "Operand is a smi and not a string") \
V(kOperandIsASmi, "Operand is a smi") \
@@ -1230,38 +1200,58 @@ class MaybeObject BASE_EMBEDDED {
V(kOperandIsNotAString, "Operand is not a string") \
V(kOperandIsNotSmi, "Operand is not smi") \
V(kOperandNotANumber, "Operand not a number") \
- V(kOptimizedTooManyTimes, "optimized too many times") \
+ V(kObjectTagged, "The object is tagged") \
+ V(kObjectNotTagged, "The object is not tagged") \
+ V(kOptimizationDisabled, "Optimization is disabled") \
+ V(kOptimizedTooManyTimes, "Optimized too many times") \
V(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister, \
"Out of virtual registers while trying to allocate temp register") \
- V(kParseScopeError, "parse/scope error") \
- V(kPossibleDirectCallToEval, "possible direct call to eval") \
+ V(kParseScopeError, "Parse/scope error") \
+ V(kPossibleDirectCallToEval, "Possible direct call to eval") \
+ V(kPreconditionsWereNotMet, "Preconditions were not met") \
V(kPropertyAllocationCountFailed, "Property allocation count failed") \
V(kReceivedInvalidReturnAddress, "Received invalid return address") \
V(kReferenceToAVariableWhichRequiresDynamicLookup, \
- "reference to a variable which requires dynamic lookup") \
+ "Reference to a variable which requires dynamic lookup") \
V(kReferenceToGlobalLexicalVariable, \
- "reference to global lexical variable") \
- V(kReferenceToUninitializedVariable, "reference to uninitialized variable") \
+ "Reference to global lexical variable") \
+ V(kReferenceToUninitializedVariable, "Reference to uninitialized variable") \
V(kRegisterDidNotMatchExpectedRoot, "Register did not match expected root") \
- V(kRegisterWasClobbered, "register was clobbered") \
+ V(kRegisterWasClobbered, "Register was clobbered") \
+ V(kRememberedSetPointerInNewSpace, "Remembered set pointer is in new space") \
+ V(kReturnAddressNotFoundInFrame, "Return address not found in frame") \
+ V(kRhsHasBeenClobbered, "Rhs has been clobbered") \
V(kScopedBlock, "ScopedBlock") \
V(kSmiAdditionOverflow, "Smi addition overflow") \
V(kSmiSubtractionOverflow, "Smi subtraction overflow") \
- V(kStackFrameTypesMustMatch, "stack frame types must match") \
+ V(kStackAccessBelowStackPointer, "Stack access below stack pointer") \
+ V(kStackFrameTypesMustMatch, "Stack frame types must match") \
V(kSwitchStatementMixedOrNonLiteralSwitchLabels, \
"SwitchStatement: mixed or non-literal switch labels") \
V(kSwitchStatementTooManyClauses, "SwitchStatement: too many clauses") \
+ V(kTheCurrentStackPointerIsBelowCsp, \
+ "The current stack pointer is below csp") \
V(kTheInstructionShouldBeALui, "The instruction should be a lui") \
V(kTheInstructionShouldBeAnOri, "The instruction should be an ori") \
V(kTheInstructionToPatchShouldBeALoadFromPc, \
"The instruction to patch should be a load from pc") \
+ V(kTheInstructionToPatchShouldBeALoadFromPp, \
+ "The instruction to patch should be a load from pp") \
+ V(kTheInstructionToPatchShouldBeAnLdrLiteral, \
+ "The instruction to patch should be a ldr literal") \
V(kTheInstructionToPatchShouldBeALui, \
"The instruction to patch should be a lui") \
V(kTheInstructionToPatchShouldBeAnOri, \
"The instruction to patch should be an ori") \
- V(kTooManyParametersLocals, "too many parameters/locals") \
- V(kTooManyParameters, "too many parameters") \
+ V(kTheSourceAndDestinationAreTheSame, \
+ "The source and destination are the same") \
+ V(kTheStackPointerIsNotAligned, "The stack pointer is not aligned.") \
+ V(kTheStackWasCorruptedByMacroAssemblerCall, \
+ "The stack was corrupted by MacroAssembler::Call()") \
+ V(kTooManyParametersLocals, "Too many parameters/locals") \
+ V(kTooManyParameters, "Too many parameters") \
V(kTooManySpillSlotsNeededForOSR, "Too many spill slots needed for OSR") \
+ V(kToOperand32UnsupportedImmediate, "ToOperand32 unsupported immediate.") \
V(kToOperandIsDoubleRegisterUnimplemented, \
"ToOperand IsDoubleRegister unimplemented") \
V(kToOperandUnsupportedDoubleImmediate, \
@@ -1270,10 +1260,12 @@ class MaybeObject BASE_EMBEDDED {
V(kTryFinallyStatement, "TryFinallyStatement") \
V(kUnableToEncodeValueAsSmi, "Unable to encode value as smi") \
V(kUnalignedAllocationInNewSpace, "Unaligned allocation in new space") \
+ V(kUnalignedCellInWriteBarrier, "Unaligned cell in write barrier") \
V(kUndefinedValueNotLoaded, "Undefined value not loaded") \
V(kUndoAllocationOfNonAllocatedMemory, \
"Undo allocation of non allocated memory") \
V(kUnexpectedAllocationTop, "Unexpected allocation top") \
+ V(kUnexpectedColorFound, "Unexpected color bit pattern found") \
V(kUnexpectedElementsKindInArrayConstructor, \
"Unexpected ElementsKind in array constructor") \
V(kUnexpectedFallthroughFromCharCodeAtSlowCase, \
@@ -1300,34 +1292,39 @@ class MaybeObject BASE_EMBEDDED {
"Unexpected initial map for InternalArray function") \
V(kUnexpectedLevelAfterReturnFromApiCall, \
"Unexpected level after return from api call") \
+ V(kUnexpectedNegativeValue, "Unexpected negative value") \
V(kUnexpectedNumberOfPreAllocatedPropertyFields, \
"Unexpected number of pre-allocated property fields") \
+ V(kUnexpectedFPCRMode, "Unexpected FPCR mode.") \
+ V(kUnexpectedSmi, "Unexpected smi value") \
V(kUnexpectedStringFunction, "Unexpected String function") \
V(kUnexpectedStringType, "Unexpected string type") \
V(kUnexpectedStringWrapperInstanceSize, \
"Unexpected string wrapper instance size") \
V(kUnexpectedTypeForRegExpDataFixedArrayExpected, \
"Unexpected type for RegExp data, FixedArray expected") \
+ V(kUnexpectedValue, "Unexpected value") \
V(kUnexpectedUnusedPropertiesOfStringWrapper, \
"Unexpected unused properties of string wrapper") \
+ V(kUnimplemented, "unimplemented") \
V(kUninitializedKSmiConstantRegister, "Uninitialized kSmiConstantRegister") \
- V(kUnknown, "unknown") \
+ V(kUnknown, "Unknown") \
V(kUnsupportedConstCompoundAssignment, \
- "unsupported const compound assignment") \
+ "Unsupported const compound assignment") \
V(kUnsupportedCountOperationWithConst, \
- "unsupported count operation with const") \
- V(kUnsupportedDoubleImmediate, "unsupported double immediate") \
- V(kUnsupportedLetCompoundAssignment, "unsupported let compound assignment") \
+ "Unsupported count operation with const") \
+ V(kUnsupportedDoubleImmediate, "Unsupported double immediate") \
+ V(kUnsupportedLetCompoundAssignment, "Unsupported let compound assignment") \
V(kUnsupportedLookupSlotInDeclaration, \
- "unsupported lookup slot in declaration") \
+ "Unsupported lookup slot in declaration") \
V(kUnsupportedNonPrimitiveCompare, "Unsupported non-primitive compare") \
V(kUnsupportedPhiUseOfArguments, "Unsupported phi use of arguments") \
V(kUnsupportedPhiUseOfConstVariable, \
"Unsupported phi use of const variable") \
- V(kUnsupportedTaggedImmediate, "unsupported tagged immediate") \
+ V(kUnsupportedTaggedImmediate, "Unsupported tagged immediate") \
V(kVariableResolvedToWithContext, "Variable resolved to with context") \
V(kWeShouldNotHaveAnEmptyLexicalContext, \
- "we should not have an empty lexical context") \
+ "We should not have an empty lexical context") \
V(kWithStatement, "WithStatement") \
V(kWrongAddressOrValuePassedToRecordWrite, \
"Wrong address or value passed to RecordWrite") \
@@ -1349,9 +1346,9 @@ const char* GetBailoutReason(BailoutReason reason);
// object hierarchy.
// Object does not use any virtual functions to avoid the
// allocation of the C++ vtable.
-// Since Smi and Failure are subclasses of Object no
+// Since both Smi and HeapObject are subclasses of Object no
// data members can be present in Object.
-class Object : public MaybeObject {
+class Object {
public:
// Type testing.
bool IsObject() { return true; }
@@ -1372,17 +1369,18 @@ class Object : public MaybeObject {
INLINE(bool IsSpecObject());
INLINE(bool IsSpecFunction());
+ INLINE(bool IsTemplateInfo());
bool IsCallable();
// Oddball testing.
INLINE(bool IsUndefined());
INLINE(bool IsNull());
- INLINE(bool IsTheHole()); // Shadows MaybeObject's implementation.
+ INLINE(bool IsTheHole());
+ INLINE(bool IsException());
INLINE(bool IsUninitialized());
INLINE(bool IsTrue());
INLINE(bool IsFalse());
inline bool IsArgumentsMarker();
- inline bool NonFailureIsHeapObject();
// Filler objects (fillers and free space objects).
inline bool IsFiller();
@@ -1431,8 +1429,11 @@ class Object : public MaybeObject {
return true;
}
- inline MaybeObject* AllocateNewStorageFor(Heap* heap,
- Representation representation);
+ Handle<HeapType> OptimalType(Isolate* isolate, Representation representation);
+
+ inline static Handle<Object> NewStorageFor(Isolate* isolate,
+ Handle<Object> object,
+ Representation representation);
// Returns true if the object is of the correct type to be used as a
// implementation of a JSObject's elements.
@@ -1440,72 +1441,69 @@ class Object : public MaybeObject {
inline bool HasSpecificClassOf(String* name);
- MUST_USE_RESULT MaybeObject* ToObject(Isolate* isolate); // ECMA-262 9.9.
bool BooleanValue(); // ECMA-262 9.2.
// Convert to a JSObject if needed.
// native_context is used when creating wrapper object.
- MUST_USE_RESULT MaybeObject* ToObject(Context* native_context);
+ static inline MaybeHandle<JSReceiver> ToObject(Isolate* isolate,
+ Handle<Object> object);
+ static MaybeHandle<JSReceiver> ToObject(Isolate* isolate,
+ Handle<Object> object,
+ Handle<Context> context);
// Converts this to a Smi if possible.
- // Failure is returned otherwise.
- MUST_USE_RESULT inline MaybeObject* ToSmi();
-
- void Lookup(Name* name, LookupResult* result);
-
- // Property access.
- MUST_USE_RESULT inline MaybeObject* GetProperty(Name* key);
- MUST_USE_RESULT inline MaybeObject* GetProperty(
- Name* key,
- PropertyAttributes* attributes);
-
- // TODO(yangguo): this should eventually replace the non-handlified version.
- static Handle<Object> GetPropertyWithReceiver(Handle<Object> object,
- Handle<Object> receiver,
- Handle<Name> name,
- PropertyAttributes* attributes);
- MUST_USE_RESULT MaybeObject* GetPropertyWithReceiver(
- Object* receiver,
- 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<Name> key,
- PropertyAttributes* attributes);
+ static MUST_USE_RESULT inline MaybeHandle<Smi> ToSmi(Isolate* isolate,
+ Handle<Object> object);
+
+ void Lookup(Handle<Name> name, LookupResult* result);
- MUST_USE_RESULT static MaybeObject* GetPropertyOrFail(
+ MUST_USE_RESULT static MaybeHandle<Object> GetProperty(LookupIterator* it);
+ MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
Handle<Object> object,
+ Handle<Name> key);
+ MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
+ Isolate* isolate,
+ Handle<Object> object,
+ const char* key);
+ MUST_USE_RESULT static inline MaybeHandle<Object> GetProperty(
+ Handle<Object> object,
+ Handle<Name> key);
+
+ MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithAccessor(
Handle<Object> receiver,
- LookupResult* result,
- Handle<Name> key,
- PropertyAttributes* attributes);
-
- MUST_USE_RESULT MaybeObject* GetProperty(Object* receiver,
- LookupResult* result,
- Name* key,
- PropertyAttributes* attributes);
-
- MUST_USE_RESULT MaybeObject* GetPropertyWithDefinedGetter(Object* receiver,
- JSReceiver* getter);
-
- static Handle<Object> GetElement(Isolate* isolate,
- Handle<Object> object,
- uint32_t index);
- MUST_USE_RESULT inline MaybeObject* GetElement(Isolate* isolate,
- uint32_t index);
- // For use when we know that no exception can be thrown.
- inline Object* GetElementNoExceptionThrown(Isolate* isolate, uint32_t index);
- MUST_USE_RESULT MaybeObject* GetElementWithReceiver(Isolate* isolate,
- Object* receiver,
- uint32_t index);
+ Handle<Name> name,
+ Handle<JSObject> holder,
+ Handle<Object> structure);
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithCallback(
+ Handle<Object> receiver,
+ Handle<Name> name,
+ Handle<Object> value,
+ Handle<JSObject> holder,
+ Handle<Object> structure,
+ StrictMode strict_mode);
+
+ MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
+ Handle<Object> receiver,
+ Handle<JSReceiver> getter);
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithDefinedSetter(
+ Handle<Object> receiver,
+ Handle<JSReceiver> setter,
+ Handle<Object> value);
+
+ MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
+ Isolate* isolate,
+ Handle<Object> object,
+ uint32_t index);
+
+ MUST_USE_RESULT static MaybeHandle<Object> GetElementWithReceiver(
+ Isolate* isolate,
+ Handle<Object> object,
+ Handle<Object> receiver,
+ uint32_t index);
// Return the object's prototype (might be Heap::null_value()).
Object* GetPrototype(Isolate* isolate);
- Map* GetMarkerMap(Isolate* isolate);
+ static Handle<Object> GetPrototype(Isolate* isolate, Handle<Object> object);
// Returns the permanent hash code associated with this object. May return
// undefined if not yet created.
@@ -1514,16 +1512,19 @@ class Object : public MaybeObject {
// Returns the permanent hash code associated with this object depending on
// the actual object type. May create and store a hash code if needed and none
// exists.
- // TODO(rafaelw): Remove isolate parameter when objects.cc is fully
- // handlified.
- static Handle<Object> GetOrCreateHash(Handle<Object> object,
- Isolate* isolate);
+ static Handle<Smi> GetOrCreateHash(Isolate* isolate, Handle<Object> object);
// Checks whether this object has the same value as the given one. This
// function is implemented according to ES5, section 9.12 and can be used
// to implement the Harmony "egal" function.
bool SameValue(Object* other);
+ // Checks whether this object has the same value as the given one.
+ // +0 and -0 are treated equal. Everything else is the same as SameValue.
+ // This function is implemented according to ES6, section 7.2.4 and is used
+ // by ES6 Map and Set.
+ bool SameValueZero(Object* other);
+
// Tries to convert an object to an array index. Returns true and sets
// the output parameter if it succeeds.
inline bool ToArrayIndex(uint32_t* index);
@@ -1532,6 +1533,7 @@ class Object : public MaybeObject {
// < the length of the string. Used to implement [] on strings.
inline bool IsStringObjectWithCharacterAt(uint32_t index);
+ DECLARE_VERIFIER(Object)
#ifdef VERIFY_HEAP
// Verify a pointer is a valid object pointer.
static void VerifyPointer(Object* p);
@@ -1551,6 +1553,14 @@ class Object : public MaybeObject {
// Layout description.
static const int kHeaderSize = 0; // Object does not take up any space.
+#ifdef OBJECT_PRINT
+ // Prints this object with details.
+ void Print();
+ void Print(FILE* out);
+ void PrintLn();
+ void PrintLn(FILE* out);
+#endif
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
};
@@ -1593,76 +1603,6 @@ class Smi: public Object {
};
-// Failure is used for reporting out of memory situations and
-// propagating exceptions through the runtime system. Failure objects
-// are transient and cannot occur as part of the object graph.
-//
-// Failures are a single word, encoded as follows:
-// +-------------------------+---+--+--+
-// |.........unused..........|sss|tt|11|
-// +-------------------------+---+--+--+
-// 7 6 4 32 10
-//
-//
-// The low two bits, 0-1, are the failure tag, 11. The next two bits,
-// 2-3, are a failure type tag 'tt' with possible values:
-// 00 RETRY_AFTER_GC
-// 01 EXCEPTION
-// 10 INTERNAL_ERROR
-// 11 OUT_OF_MEMORY_EXCEPTION
-//
-// The next three bits, 4-6, are an allocation space tag 'sss'. The
-// allocation space tag is 000 for all failure types except
-// RETRY_AFTER_GC. For RETRY_AFTER_GC, the possible values are the
-// allocation spaces (the encoding is found in globals.h).
-
-// Failure type tag info.
-const int kFailureTypeTagSize = 2;
-const int kFailureTypeTagMask = (1 << kFailureTypeTagSize) - 1;
-
-class Failure: public MaybeObject {
- public:
- // RuntimeStubs assumes EXCEPTION = 1 in the compiler-generated code.
- enum Type {
- RETRY_AFTER_GC = 0,
- EXCEPTION = 1, // Returning this marker tells the real exception
- // is in Isolate::pending_exception.
- INTERNAL_ERROR = 2,
- OUT_OF_MEMORY_EXCEPTION = 3
- };
-
- inline Type type() const;
-
- // Returns the space that needs to be collected for RetryAfterGC failures.
- inline AllocationSpace allocation_space() const;
-
- inline bool IsInternalError() const;
- inline bool IsOutOfMemoryException() const;
-
- static inline Failure* RetryAfterGC(AllocationSpace space);
- static inline Failure* RetryAfterGC(); // NEW_SPACE
- static inline Failure* Exception();
- static inline Failure* InternalError();
- // 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);
-
- // Dispatched behavior.
- void FailurePrint(FILE* out = stdout);
- void FailurePrint(StringStream* accumulator);
-
- DECLARE_VERIFIER(Failure)
-
- private:
- inline intptr_t value() const;
- static inline Failure* Construct(Type type, intptr_t value = 0);
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(Failure);
-};
-
-
// Heap objects typically have a map pointer in their first word. However,
// during GC other data (e.g. mark bits, forwarding addresses) is sometimes
// encoded in the first word. The class MapWord is an abstraction of the
@@ -1723,6 +1663,15 @@ class HeapObject: public Object {
// of primitive (non-JS) objects like strings, heap numbers etc.
inline void set_map_no_write_barrier(Map* value);
+ // Get the map using acquire load.
+ inline Map* synchronized_map();
+ inline MapWord synchronized_map_word();
+
+ // Set the map using release store
+ inline void synchronized_set_map(Map* value);
+ inline void synchronized_set_map_no_write_barrier(Map* value);
+ inline void synchronized_set_map_word(MapWord map_word);
+
// During garbage collection, the map word of a heap object does not
// necessarily contain a map pointer.
inline MapWord map_word();
@@ -1802,7 +1751,7 @@ class HeapObject: public Object {
static const int kMapOffset = Object::kHeaderSize;
static const int kHeaderSize = kMapOffset + kPointerSize;
- STATIC_CHECK(kMapOffset == Internals::kHeapObjectMapOffset);
+ STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset);
protected:
// helpers for calling an ObjectVisitor to iterate over pointers in the
@@ -1810,6 +1759,8 @@ class HeapObject: public Object {
inline void IteratePointers(ObjectVisitor* v, int start, int end);
// as above, for the single element at "offset"
inline void IteratePointer(ObjectVisitor* v, int offset);
+ // as above, for the next code link of a code object.
+ inline void IterateNextCodeLink(ObjectVisitor* v, int offset);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
@@ -1880,11 +1831,18 @@ class HeapNumber: public HeapObject {
// Layout description.
static const int kValueOffset = HeapObject::kHeaderSize;
// IEEE doubles are two 32 bit words. The first is just mantissa, the second
- // is a mixture of sign, exponent and mantissa. Our current platforms are all
- // little endian apart from non-EABI arm which is little endian with big
- // endian floating point word ordering!
+ // is a mixture of sign, exponent and mantissa. The offsets of two 32 bit
+ // words within double numbers are endian dependent and they are set
+ // accordingly.
+#if defined(V8_TARGET_LITTLE_ENDIAN)
static const int kMantissaOffset = kValueOffset;
static const int kExponentOffset = kValueOffset + 4;
+#elif defined(V8_TARGET_BIG_ENDIAN)
+ static const int kMantissaOffset = kValueOffset + 4;
+ static const int kExponentOffset = kValueOffset;
+#else
+#error Unknown byte ordering
+#endif
static const int kSize = kValueOffset + kDoubleSize;
static const uint32_t kSignMask = 0x80000000u;
@@ -1956,32 +1914,35 @@ class JSReceiver: public HeapObject {
static inline JSReceiver* cast(Object* obj);
// Implementation of [[Put]], ECMA-262 5th edition, section 8.12.5.
- static Handle<Object> SetProperty(Handle<JSReceiver> object,
- Handle<Name> key,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictModeFlag strict_mode,
- StoreFromKeyed store_mode =
- MAY_BE_STORE_FROM_KEYED);
- static Handle<Object> SetElement(Handle<JSReceiver> object,
- uint32_t index,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictModeFlag strict_mode);
+ MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
+ Handle<JSReceiver> object,
+ Handle<Name> key,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode,
+ StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
+ MUST_USE_RESULT static MaybeHandle<Object> SetElement(
+ Handle<JSReceiver> object,
+ uint32_t index,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode);
// Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6.
static inline bool HasProperty(Handle<JSReceiver> object, Handle<Name> name);
- static inline bool HasLocalProperty(Handle<JSReceiver>, Handle<Name> name);
+ static inline bool HasOwnProperty(Handle<JSReceiver>, Handle<Name> name);
static inline bool HasElement(Handle<JSReceiver> object, uint32_t index);
- static inline bool HasLocalElement(Handle<JSReceiver> object, uint32_t index);
+ static inline bool HasOwnElement(Handle<JSReceiver> object, uint32_t index);
// Implementation of [[Delete]], ECMA-262 5th edition, section 8.12.7.
- static Handle<Object> DeleteProperty(Handle<JSReceiver> object,
- Handle<Name> name,
- DeleteMode mode = NORMAL_DELETION);
- static Handle<Object> DeleteElement(Handle<JSReceiver> object,
- uint32_t index,
- DeleteMode mode = NORMAL_DELETION);
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteProperty(
+ Handle<JSReceiver> object,
+ Handle<Name> name,
+ DeleteMode mode = NORMAL_DELETION);
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteElement(
+ Handle<JSReceiver> object,
+ uint32_t index,
+ DeleteMode mode = NORMAL_DELETION);
// Tests for the fast common case for property enumeration.
bool IsSimpleEnum();
@@ -1993,13 +1954,20 @@ class JSReceiver: public HeapObject {
// function that was used to instantiate the object).
String* constructor_name();
- inline PropertyAttributes GetPropertyAttribute(Name* name);
- PropertyAttributes GetPropertyAttributeWithReceiver(JSReceiver* receiver,
- Name* name);
- PropertyAttributes GetLocalPropertyAttribute(Name* name);
+ static inline PropertyAttributes GetPropertyAttributes(
+ Handle<JSReceiver> object,
+ Handle<Name> name);
+ static PropertyAttributes GetPropertyAttributes(LookupIterator* it);
+ static PropertyAttributes GetOwnPropertyAttributes(
+ Handle<JSReceiver> object,
+ Handle<Name> name);
- inline PropertyAttributes GetElementAttribute(uint32_t index);
- inline PropertyAttributes GetLocalElementAttribute(uint32_t index);
+ static inline PropertyAttributes GetElementAttribute(
+ Handle<JSReceiver> object,
+ uint32_t index);
+ static inline PropertyAttributes GetOwnElementAttribute(
+ Handle<JSReceiver> object,
+ uint32_t index);
// Return the object's prototype (might be Heap::null_value()).
inline Object* GetPrototype();
@@ -2013,35 +1981,32 @@ class JSReceiver: public HeapObject {
// Retrieves a permanent object identity hash code. May create and store a
// hash code if needed and none exists.
- inline static Handle<Object> GetOrCreateIdentityHash(
+ inline static Handle<Smi> GetOrCreateIdentityHash(
Handle<JSReceiver> object);
// Lookup a property. If found, the result is valid and has
// detailed information.
- void LocalLookup(Name* name, LookupResult* result,
- bool search_hidden_prototypes = false);
- void Lookup(Name* name, LookupResult* result);
+ void LookupOwn(Handle<Name> name, LookupResult* result,
+ bool search_hidden_prototypes = false);
+ void Lookup(Handle<Name> name, LookupResult* result);
- protected:
- Smi* GenerateIdentityHash();
+ enum KeyCollectionType { OWN_ONLY, INCLUDE_PROTOS };
- static Handle<Object> SetPropertyWithDefinedSetter(Handle<JSReceiver> object,
- Handle<JSReceiver> setter,
- Handle<Object> value);
+ // Computes the enumerable keys for a JSObject. Used for implementing
+ // "for (n in object) { }".
+ MUST_USE_RESULT static MaybeHandle<FixedArray> GetKeys(
+ Handle<JSReceiver> object,
+ KeyCollectionType type);
private:
- PropertyAttributes GetPropertyAttributeForResult(JSReceiver* receiver,
- LookupResult* result,
- Name* name,
- bool continue_search);
-
- static Handle<Object> SetProperty(Handle<JSReceiver> receiver,
- LookupResult* result,
- Handle<Name> key,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictModeFlag strict_mode,
- StoreFromKeyed store_from_keyed);
+ MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
+ Handle<JSReceiver> receiver,
+ LookupResult* result,
+ Handle<Name> key,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode,
+ StoreFromKeyed store_from_keyed);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
};
@@ -2049,6 +2014,10 @@ class JSReceiver: public HeapObject {
// Forward declaration for JSObject::GetOrCreateHiddenPropertiesHashTable.
class ObjectHashTable;
+// Forward declaration for JSObject::Copy.
+class AllocationSite;
+
+
// The JSObject describes real heap allocated JavaScript objects with
// properties.
// Note that the map of JSObject changes during execution to enable inline
@@ -2072,18 +2041,21 @@ class JSObject: public JSReceiver {
// In the fast mode elements is a FixedArray and so each element can
// be quickly accessed. This fact is used in the generated code. The
// elements array can have one of three maps in this mode:
- // fixed_array_map, non_strict_arguments_elements_map or
+ // fixed_array_map, sloppy_arguments_elements_map or
// fixed_cow_array_map (for copy-on-write arrays). In the latter case
// the elements array may be shared by a few objects and so before
// writing to any element the array must be copied. Use
// EnsureWritableFastElements in this case.
//
// In the slow mode the elements is either a NumberDictionary, an
- // ExternalArray, or a FixedArray parameter map for a (non-strict)
+ // ExternalArray, or a FixedArray parameter map for a (sloppy)
// arguments object.
DECL_ACCESSORS(elements, FixedArrayBase)
inline void initialize_elements();
- MUST_USE_RESULT inline MaybeObject* ResetElements();
+ static void ResetElements(Handle<JSObject> object);
+ static inline void SetMapAndElements(Handle<JSObject> object,
+ Handle<Map> map,
+ Handle<FixedArrayBase> elements);
inline ElementsKind GetElementsKind();
inline ElementsAccessor* GetElementsAccessor();
// Returns true if an object has elements of FAST_SMI_ELEMENTS ElementsKind.
@@ -2101,33 +2073,40 @@ class JSObject: public JSReceiver {
// Returns true if an object has elements of FAST_HOLEY_*_ELEMENTS
// ElementsKind.
inline bool HasFastHoleyElements();
- inline bool HasNonStrictArgumentsElements();
+ inline bool HasSloppyArgumentsElements();
inline bool HasDictionaryElements();
- inline bool HasExternalPixelElements();
+
+ inline bool HasExternalUint8ClampedElements();
inline bool HasExternalArrayElements();
- inline bool HasExternalByteElements();
- inline bool HasExternalUnsignedByteElements();
- inline bool HasExternalShortElements();
- inline bool HasExternalUnsignedShortElements();
- inline bool HasExternalIntElements();
- inline bool HasExternalUnsignedIntElements();
- inline bool HasExternalFloatElements();
- inline bool HasExternalDoubleElements();
+ inline bool HasExternalInt8Elements();
+ inline bool HasExternalUint8Elements();
+ inline bool HasExternalInt16Elements();
+ inline bool HasExternalUint16Elements();
+ inline bool HasExternalInt32Elements();
+ inline bool HasExternalUint32Elements();
+ inline bool HasExternalFloat32Elements();
+ inline bool HasExternalFloat64Elements();
+
+ inline bool HasFixedTypedArrayElements();
+
+ inline bool HasFixedUint8ClampedElements();
+ inline bool HasFixedArrayElements();
+ inline bool HasFixedInt8Elements();
+ inline bool HasFixedUint8Elements();
+ inline bool HasFixedInt16Elements();
+ inline bool HasFixedUint16Elements();
+ inline bool HasFixedInt32Elements();
+ inline bool HasFixedUint32Elements();
+ inline bool HasFixedFloat32Elements();
+ inline bool HasFixedFloat64Elements();
+
bool HasFastArgumentsElements();
bool HasDictionaryArgumentsElements();
inline SeededNumberDictionary* element_dictionary(); // Gets slow elements.
- inline bool ShouldTrackAllocationInfo();
-
- inline void set_map_and_elements(
- Map* map,
- FixedArrayBase* value,
- WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
-
// Requires: HasFastElements().
static Handle<FixedArray> EnsureWritableFastElements(
Handle<JSObject> object);
- MUST_USE_RESULT inline MaybeObject* EnsureWritableFastElements();
// Collects elements starting at index 0.
// Undefined values are placed after non-undefined values.
@@ -2135,48 +2114,44 @@ class JSObject: public JSReceiver {
static Handle<Object> PrepareElementsForSort(Handle<JSObject> object,
uint32_t limit);
// As PrepareElementsForSort, but only on objects where elements is
- // a dictionary, and it will stay a dictionary.
+ // a dictionary, and it will stay a dictionary. Collates undefined and
+ // unexisting elements below limit from position zero of the elements.
static Handle<Object> PrepareSlowElementsForSort(Handle<JSObject> object,
uint32_t limit);
- MUST_USE_RESULT MaybeObject* PrepareSlowElementsForSort(uint32_t limit);
-
- static Handle<Object> GetPropertyWithCallback(Handle<JSObject> object,
- Handle<Object> receiver,
- Handle<Object> structure,
- Handle<Name> name);
- static Handle<Object> SetPropertyWithCallback(
- Handle<JSObject> object,
- Handle<Object> structure,
- Handle<Name> name,
- Handle<Object> value,
- Handle<JSObject> holder,
- StrictModeFlag strict_mode);
-
- static Handle<Object> SetPropertyWithInterceptor(
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithInterceptor(
Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode);
+ StrictMode strict_mode);
- static Handle<Object> SetPropertyForResult(
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyForResult(
Handle<JSObject> object,
LookupResult* result,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED);
- static Handle<Object> SetLocalPropertyIgnoreAttributes(
+ // SetLocalPropertyIgnoreAttributes converts callbacks to fields. We need to
+ // grant an exemption to ExecutableAccessor callbacks in some cases.
+ enum ExecutableAccessorInfoHandling {
+ DEFAULT_HANDLING,
+ DONT_FORCE_FIELD
+ };
+
+ MUST_USE_RESULT static MaybeHandle<Object> SetOwnPropertyIgnoreAttributes(
Handle<JSObject> object,
Handle<Name> key,
Handle<Object> value,
PropertyAttributes attributes,
ValueType value_type = OPTIMAL_REPRESENTATION,
StoreMode mode = ALLOW_AS_CONSTANT,
- ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK);
+ ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
+ StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
+ ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING);
static inline Handle<String> ExpectedTransitionKey(Handle<Map> map);
static inline Handle<Map> ExpectedTransitionTarget(Handle<Map> map);
@@ -2195,17 +2170,19 @@ class JSObject: public JSReceiver {
static void MigrateInstance(Handle<JSObject> instance);
// Migrates the given object only if the target map is already available,
- // or returns an empty handle if such a map is not yet available.
- static Handle<Object> TryMigrateInstance(Handle<JSObject> instance);
+ // or returns false if such a map is not yet available.
+ static bool TryMigrateInstance(Handle<JSObject> instance);
// Retrieve a value in a normalized object given a lookup result.
// Handles the special representation of JS global objects.
- Object* GetNormalizedProperty(LookupResult* result);
+ Object* GetNormalizedProperty(const LookupResult* result);
+ static Handle<Object> GetNormalizedProperty(Handle<JSObject> object,
+ const LookupResult* result);
// Sets the property value in a normalized object given a lookup result.
// Handles the special representation of JS global objects.
static void SetNormalizedProperty(Handle<JSObject> object,
- LookupResult* result,
+ const LookupResult* result,
Handle<Object> value);
// Sets the property value in a normalized object given (key, value, details).
@@ -2222,26 +2199,24 @@ class JSObject: public JSReceiver {
InterceptorInfo* GetIndexedInterceptor();
// Used from JSReceiver.
- PropertyAttributes GetPropertyAttributePostInterceptor(JSObject* receiver,
- Name* name,
- bool continue_search);
- PropertyAttributes GetPropertyAttributeWithInterceptor(JSObject* receiver,
- Name* name,
- bool continue_search);
- PropertyAttributes GetPropertyAttributeWithFailedAccessCheck(
- Object* receiver,
- LookupResult* result,
- Name* name,
- bool continue_search);
- PropertyAttributes GetElementAttributeWithReceiver(JSReceiver* receiver,
- uint32_t index,
- bool continue_search);
+ static Maybe<PropertyAttributes> GetPropertyAttributesWithInterceptor(
+ Handle<JSObject> holder,
+ Handle<Object> receiver,
+ Handle<Name> name);
+ static PropertyAttributes GetPropertyAttributesWithFailedAccessCheck(
+ LookupIterator* it);
+ static PropertyAttributes GetElementAttributeWithReceiver(
+ Handle<JSObject> object,
+ Handle<JSReceiver> receiver,
+ uint32_t index,
+ bool check_prototype);
// Retrieves an AccessorPair property from the given object. Might return
// undefined if the property doesn't exist or is of a different kind.
- static Handle<Object> GetAccessor(Handle<JSObject> object,
- Handle<Name> name,
- AccessorComponent component);
+ MUST_USE_RESULT static MaybeHandle<Object> GetAccessor(
+ Handle<JSObject> object,
+ Handle<Name> name,
+ AccessorComponent component);
// Defines an AccessorPair property on the given object.
// TODO(mstarzinger): Rename to SetAccessor() and return empty handle on
@@ -2254,36 +2229,23 @@ class JSObject: public JSReceiver {
v8::AccessControl access_control = v8::DEFAULT);
// Defines an AccessorInfo property on the given object.
- static Handle<Object> SetAccessor(Handle<JSObject> object,
- Handle<AccessorInfo> info);
-
- static Handle<Object> GetPropertyWithInterceptor(
+ MUST_USE_RESULT static MaybeHandle<Object> SetAccessor(
Handle<JSObject> object,
- Handle<Object> receiver,
- Handle<Name> name,
- PropertyAttributes* attributes);
- static Handle<Object> GetPropertyPostInterceptor(
+ Handle<AccessorInfo> info);
+
+ MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithInterceptor(
Handle<JSObject> object,
Handle<Object> receiver,
- Handle<Name> name,
- PropertyAttributes* attributes);
- MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor(
- Object* receiver,
- Name* name,
- PropertyAttributes* attributes);
+ Handle<Name> name);
// Returns true if this is an instance of an api function and has
// been modified since it was created. May give false positives.
bool IsDirty();
- // If the receiver is a JSGlobalProxy this method will return its prototype,
- // otherwise the result is the receiver itself.
- inline Object* BypassGlobalProxy();
-
// Accessors for hidden properties object.
//
- // Hidden properties are not local properties of the object itself.
- // Instead they are stored in an auxiliary structure kept as a local
+ // Hidden properties are not own properties of the object itself.
+ // Instead they are stored in an auxiliary structure kept as an own
// 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
@@ -2297,36 +2259,42 @@ class JSObject: public JSReceiver {
// Gets the value of a hidden property with the given key. Returns the hole
// if the property doesn't exist (or if called on a detached proxy),
// otherwise returns the value set for the key.
- Object* GetHiddenProperty(Name* key);
+ Object* GetHiddenProperty(Handle<Name> key);
// Deletes a hidden property. Deleting a non-existing property is
// considered successful.
static void DeleteHiddenProperty(Handle<JSObject> object,
Handle<Name> key);
// Returns true if the object has a property with the hidden string as name.
- bool HasHiddenProperties();
+ static bool HasHiddenProperties(Handle<JSObject> object);
static void SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash);
- inline void ValidateElements();
+ static inline void ValidateElements(Handle<JSObject> object);
// Makes sure that this object can contain HeapObject as elements.
static inline void EnsureCanContainHeapObjectElements(Handle<JSObject> obj);
// Makes sure that this object can contain the specified elements.
- MUST_USE_RESULT inline MaybeObject* EnsureCanContainElements(
+ static inline void EnsureCanContainElements(
+ Handle<JSObject> object,
Object** elements,
uint32_t count,
EnsureElementsMode mode);
- MUST_USE_RESULT inline MaybeObject* EnsureCanContainElements(
- FixedArrayBase* elements,
+ static inline void EnsureCanContainElements(
+ Handle<JSObject> object,
+ Handle<FixedArrayBase> elements,
uint32_t length,
EnsureElementsMode mode);
- MUST_USE_RESULT MaybeObject* EnsureCanContainElements(
+ static void EnsureCanContainElements(
+ Handle<JSObject> object,
Arguments* arguments,
uint32_t first_arg,
uint32_t arg_count,
EnsureElementsMode mode);
+ // Would we convert a fast elements array to dictionary mode given
+ // an access at key?
+ bool WouldConvertToSlowElements(Handle<Object> key);
// Do we want to keep the elements in fast case when increasing the
// capacity?
bool ShouldConvertToSlowElements(int new_capacity);
@@ -2347,33 +2315,42 @@ class JSObject: public JSReceiver {
}
// These methods do not perform access checks!
- AccessorPair* GetLocalPropertyAccessorPair(Name* name);
- AccessorPair* GetLocalElementAccessorPair(uint32_t index);
+ MUST_USE_RESULT static MaybeHandle<AccessorPair> GetOwnPropertyAccessorPair(
+ Handle<JSObject> object,
+ Handle<Name> name);
+ MUST_USE_RESULT static MaybeHandle<AccessorPair> GetOwnElementAccessorPair(
+ Handle<JSObject> object,
+ uint32_t index);
- static Handle<Object> SetFastElement(Handle<JSObject> object, uint32_t index,
- Handle<Object> value,
- StrictModeFlag strict_mode,
- bool check_prototype);
+ MUST_USE_RESULT static MaybeHandle<Object> SetFastElement(
+ Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ StrictMode strict_mode,
+ bool check_prototype);
- static Handle<Object> SetOwnElement(Handle<JSObject> object,
- uint32_t index,
- Handle<Object> value,
- StrictModeFlag strict_mode);
+ MUST_USE_RESULT static MaybeHandle<Object> SetOwnElement(
+ Handle<JSObject> object,
+ uint32_t index,
+ Handle<Object> value,
+ StrictMode strict_mode);
// Empty handle is returned if the element cannot be set to the given value.
- static Handle<Object> SetElement(
+ MUST_USE_RESULT static MaybeHandle<Object> SetElement(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool check_prototype = true,
SetPropertyMode set_mode = SET_PROPERTY);
// Returns the index'th element.
// The undefined object if index is out of bounds.
- MUST_USE_RESULT MaybeObject* GetElementWithInterceptor(Object* receiver,
- uint32_t index);
+ MUST_USE_RESULT static MaybeHandle<Object> GetElementWithInterceptor(
+ Handle<JSObject> object,
+ Handle<Object> receiver,
+ uint32_t index);
enum SetFastElementsCapacitySmiMode {
kAllowSmiElements,
@@ -2381,15 +2358,11 @@ class JSObject: public JSReceiver {
kDontAllowSmiElements
};
- static Handle<FixedArray> SetFastElementsCapacityAndLength(
- Handle<JSObject> object,
- int capacity,
- int length,
- SetFastElementsCapacitySmiMode smi_mode);
// Replace the elements' backing store with fast elements of the given
// capacity. Update the length for JSArrays. Returns the new backing
// store.
- MUST_USE_RESULT MaybeObject* SetFastElementsCapacityAndLength(
+ static Handle<FixedArray> SetFastElementsCapacityAndLength(
+ Handle<JSObject> object,
int capacity,
int length,
SetFastElementsCapacitySmiMode smi_mode);
@@ -2397,15 +2370,21 @@ class JSObject: public JSReceiver {
Handle<JSObject> object,
int capacity,
int length);
- MUST_USE_RESULT MaybeObject* SetFastDoubleElementsCapacityAndLength(
- int capacity,
- int length);
// Lookup interceptors are used for handling properties controlled by host
// objects.
inline bool HasNamedInterceptor();
inline bool HasIndexedInterceptor();
+ // Computes the enumerable keys from interceptors. Used for debug mirrors and
+ // by JSReceiver::GetKeys.
+ MUST_USE_RESULT static MaybeHandle<JSObject> GetKeysForNamedInterceptor(
+ Handle<JSObject> object,
+ Handle<JSReceiver> receiver);
+ MUST_USE_RESULT static MaybeHandle<JSObject> GetKeysForIndexedInterceptor(
+ Handle<JSObject> object,
+ Handle<JSReceiver> receiver);
+
// Support functions for v8 api (needed for correct interceptor behavior).
static bool HasRealNamedProperty(Handle<JSObject> object,
Handle<Name> key);
@@ -2424,27 +2403,27 @@ class JSObject: public JSReceiver {
inline void SetInternalField(int index, Smi* value);
// The following lookup functions skip interceptors.
- void LocalLookupRealNamedProperty(Name* name, LookupResult* result);
- void LookupRealNamedProperty(Name* name, LookupResult* result);
- void LookupRealNamedPropertyInPrototypes(Name* name, LookupResult* result);
- void LookupCallbackProperty(Name* name, LookupResult* result);
+ void LookupOwnRealNamedProperty(Handle<Name> name, LookupResult* result);
+ void LookupRealNamedProperty(Handle<Name> name, LookupResult* result);
+ void LookupRealNamedPropertyInPrototypes(Handle<Name> name,
+ LookupResult* result);
// Returns the number of properties on this object filtering out properties
// with the specified attributes (ignoring interceptors).
- int NumberOfLocalProperties(PropertyAttributes filter = NONE);
+ int NumberOfOwnProperties(PropertyAttributes filter = NONE);
// Fill in details for properties into storage starting at the specified
// index.
- void GetLocalPropertyNames(
+ void GetOwnPropertyNames(
FixedArray* storage, int index, PropertyAttributes filter = NONE);
// Returns the number of properties on this object filtering out properties
// with the specified attributes (ignoring interceptors).
- int NumberOfLocalElements(PropertyAttributes filter);
+ int NumberOfOwnElements(PropertyAttributes filter);
// Returns the number of enumerable elements (ignoring interceptors).
int NumberOfEnumElements();
// Returns the number of elements on this object filtering out elements
// with the specified attributes (ignoring interceptors).
- int GetLocalElementKeys(FixedArray* storage, PropertyAttributes filter);
+ int GetOwnElementKeys(FixedArray* storage, PropertyAttributes filter);
// Count and fill in the enumerable elements into storage.
// (storage->length() == NumberOfEnumElements()).
// If storage is NULL, will count the elements without adding
@@ -2456,22 +2435,15 @@ class JSObject: public JSReceiver {
// map and the ElementsKind set.
static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
ElementsKind to_kind);
- inline MUST_USE_RESULT MaybeObject* GetElementsTransitionMap(
- Isolate* isolate,
- ElementsKind elements_kind);
- MUST_USE_RESULT MaybeObject* GetElementsTransitionMapSlow(
- ElementsKind elements_kind);
-
static void TransitionElementsKind(Handle<JSObject> object,
ElementsKind to_kind);
- MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind to_kind);
-
- // TODO(mstarzinger): Both public because of ConvertAnsSetLocalProperty().
+ // TODO(mstarzinger): Both public because of ConvertAndSetOwnProperty().
static void MigrateToMap(Handle<JSObject> object, Handle<Map> new_map);
static void GeneralizeFieldRepresentation(Handle<JSObject> object,
int modify_index,
Representation new_representation,
+ Handle<HeapType> new_field_type,
StoreMode store_mode);
// Convert the object to use the canonical dictionary
@@ -2487,18 +2459,17 @@ class JSObject: public JSReceiver {
static Handle<SeededNumberDictionary> NormalizeElements(
Handle<JSObject> object);
- MUST_USE_RESULT MaybeObject* NormalizeElements();
-
// Transform slow named properties to fast variants.
static void TransformToFastProperties(Handle<JSObject> object,
int unused_property_fields);
// Access fast-case object properties at index.
- MUST_USE_RESULT inline MaybeObject* FastPropertyAt(
- Representation representation,
- int index);
- inline Object* RawFastPropertyAt(int index);
- inline void FastPropertyAtPut(int index, Object* value);
+ static Handle<Object> FastPropertyAt(Handle<JSObject> object,
+ Representation representation,
+ FieldIndex index);
+ inline Object* RawFastPropertyAt(FieldIndex index);
+ inline void FastPropertyAtPut(FieldIndex index, Object* value);
+ void WriteToField(int descriptor, Object* value);
// Access to in object properties.
inline int GetInObjectPropertyOffset(int index);
@@ -2509,9 +2480,10 @@ class JSObject: public JSReceiver {
= UPDATE_WRITE_BARRIER);
// Set the object's prototype (only JSReceiver and null are allowed values).
- static Handle<Object> SetPrototype(Handle<JSObject> object,
- Handle<Object> value,
- bool skip_hidden_prototypes = false);
+ MUST_USE_RESULT static MaybeHandle<Object> SetPrototype(
+ Handle<JSObject> object,
+ Handle<Object> value,
+ bool skip_hidden_prototypes = false);
// Initializes the body after properties slot, properties slot is
// initialized by set_properties. Fill the pre-allocated fields with
@@ -2526,10 +2498,11 @@ class JSObject: public JSReceiver {
bool ReferencesObject(Object* obj);
// Disalow further properties to be added to the object.
- static Handle<Object> PreventExtensions(Handle<JSObject> object);
+ MUST_USE_RESULT static MaybeHandle<Object> PreventExtensions(
+ Handle<JSObject> object);
// ES5 Object.freeze
- static Handle<Object> Freeze(Handle<JSObject> object);
+ MUST_USE_RESULT static MaybeHandle<Object> Freeze(Handle<JSObject> object);
// Called the first time an object is observed with ES7 Object.observe.
static void SetObserved(Handle<JSObject> object);
@@ -2541,11 +2514,16 @@ class JSObject: public JSReceiver {
};
static Handle<JSObject> Copy(Handle<JSObject> object);
- static Handle<JSObject> DeepCopy(Handle<JSObject> object,
- AllocationSiteUsageContext* site_context,
- DeepCopyHints hints = kNoHints);
- static Handle<JSObject> DeepWalk(Handle<JSObject> object,
- AllocationSiteCreationContext* site_context);
+ MUST_USE_RESULT static MaybeHandle<JSObject> DeepCopy(
+ Handle<JSObject> object,
+ AllocationSiteUsageContext* site_context,
+ DeepCopyHints hints = kNoHints);
+ MUST_USE_RESULT static MaybeHandle<JSObject> DeepWalk(
+ Handle<JSObject> object,
+ AllocationSiteCreationContext* site_context);
+
+ static Handle<Object> GetDataProperty(Handle<JSObject> object,
+ Handle<Name> key);
// Casting.
static inline JSObject* cast(Object* obj);
@@ -2560,9 +2538,10 @@ class JSObject: public JSReceiver {
void PrintTransitions(FILE* out = stdout);
#endif
- void PrintElementsTransition(
- FILE* file, ElementsKind from_kind, FixedArrayBase* from_elements,
- ElementsKind to_kind, FixedArrayBase* to_elements);
+ static void PrintElementsTransition(
+ FILE* file, Handle<JSObject> object,
+ ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
+ ElementsKind to_kind, Handle<FixedArrayBase> to_elements);
void PrintInstanceMigration(FILE* file, Map* original_map, Map* new_map);
@@ -2622,12 +2601,16 @@ class JSObject: public JSReceiver {
// don't want to be wasteful with long lived objects.
static const int kMaxUncheckedOldFastElementsLength = 500;
- // Note that Heap::MaxRegularSpaceAllocationSize() puts a limit on
+ // Note that Page::kMaxRegularHeapObjectSize puts a limit on
// permissible values (see the ASSERT in heap.cc).
static const int kInitialMaxFastElementArray = 100000;
+ // This constant applies only to the initial map of "$Object" aka
+ // "global.Object" and not to arbitrary other JSObject maps.
+ static const int kInitialGlobalObjectUnusedPropertiesCount = 4;
+
static const int kFastPropertiesSoftLimit = 12;
- static const int kMaxFastProperties = 64;
+ static const int kMaxFastProperties = 128;
static const int kMaxInstanceSize = 255 * kPointerSize;
// When extending the backing storage for property values, we increase
// its size by more than the 1 entry necessary, so sequentially adding fields
@@ -2639,13 +2622,15 @@ class JSObject: public JSReceiver {
static const int kElementsOffset = kPropertiesOffset + kPointerSize;
static const int kHeaderSize = kElementsOffset + kPointerSize;
- STATIC_CHECK(kHeaderSize == Internals::kJSObjectHeaderSize);
+ STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize);
class BodyDescriptor : public FlexibleBodyDescriptor<kPropertiesOffset> {
public:
static inline int SizeOf(Map* map, HeapObject* object);
};
+ Context* GetCreationContext();
+
// Enqueue change record for Object.observe. May cause GC.
static void EnqueueChangeRecord(Handle<JSObject> object,
const char* type,
@@ -2659,128 +2644,117 @@ class JSObject: public JSReceiver {
static void UpdateAllocationSite(Handle<JSObject> object,
ElementsKind to_kind);
- MUST_USE_RESULT MaybeObject* UpdateAllocationSite(ElementsKind to_kind);
// Used from Object::GetProperty().
- static Handle<Object> GetPropertyWithFailedAccessCheck(
+ MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithFailedAccessCheck(
+ LookupIterator* it);
+
+ MUST_USE_RESULT static MaybeHandle<Object> GetElementWithCallback(
Handle<JSObject> object,
Handle<Object> receiver,
- LookupResult* result,
- Handle<Name> name,
- PropertyAttributes* attributes);
-
- MUST_USE_RESULT MaybeObject* GetElementWithCallback(Object* receiver,
- Object* structure,
- uint32_t index,
- Object* holder);
- MUST_USE_RESULT PropertyAttributes GetElementAttributeWithInterceptor(
- JSReceiver* receiver,
+ Handle<Object> structure,
+ uint32_t index,
+ Handle<Object> holder);
+
+ static PropertyAttributes GetElementAttributeWithInterceptor(
+ Handle<JSObject> object,
+ Handle<JSReceiver> receiver,
uint32_t index,
bool continue_search);
- MUST_USE_RESULT PropertyAttributes GetElementAttributeWithoutInterceptor(
- JSReceiver* receiver,
+ static PropertyAttributes GetElementAttributeWithoutInterceptor(
+ Handle<JSObject> object,
+ Handle<JSReceiver> receiver,
uint32_t index,
bool continue_search);
- static Handle<Object> SetElementWithCallback(
+ MUST_USE_RESULT static MaybeHandle<Object> SetElementWithCallback(
Handle<JSObject> object,
Handle<Object> structure,
uint32_t index,
Handle<Object> value,
Handle<JSObject> holder,
- StrictModeFlag strict_mode);
- static Handle<Object> SetElementWithInterceptor(
+ StrictMode strict_mode);
+ MUST_USE_RESULT static MaybeHandle<Object> SetElementWithInterceptor(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool check_prototype,
SetPropertyMode set_mode);
- static Handle<Object> SetElementWithoutInterceptor(
+ MUST_USE_RESULT static MaybeHandle<Object> SetElementWithoutInterceptor(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool check_prototype,
SetPropertyMode set_mode);
- static Handle<Object> SetElementWithCallbackSetterInPrototypes(
+ MUST_USE_RESULT
+ static MaybeHandle<Object> SetElementWithCallbackSetterInPrototypes(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
bool* found,
- StrictModeFlag strict_mode);
- static Handle<Object> SetDictionaryElement(
+ StrictMode strict_mode);
+ MUST_USE_RESULT static MaybeHandle<Object> SetDictionaryElement(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool check_prototype,
SetPropertyMode set_mode = SET_PROPERTY);
- static Handle<Object> SetFastDoubleElement(
+ MUST_USE_RESULT static MaybeHandle<Object> SetFastDoubleElement(
Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool check_prototype = true);
// Searches the prototype chain for property 'name'. If it is found and
// has a setter, invoke it and set '*done' to true. If it is found and is
// read-only, reject and set '*done' to true. Otherwise, set '*done' to
// false. Can throw and return an empty handle with '*done==true'.
- static Handle<Object> SetPropertyViaPrototypes(
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyViaPrototypes(
Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool* done);
- static Handle<Object> SetPropertyPostInterceptor(
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyPostInterceptor(
Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode);
- static Handle<Object> SetPropertyUsingTransition(
+ StrictMode strict_mode);
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyUsingTransition(
Handle<JSObject> object,
LookupResult* lookup,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes);
- static Handle<Object> SetPropertyWithFailedAccessCheck(
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithFailedAccessCheck(
Handle<JSObject> object,
LookupResult* result,
Handle<Name> name,
Handle<Object> value,
bool check_prototype,
- StrictModeFlag strict_mode);
+ StrictMode strict_mode);
// Add a property to an object.
- static Handle<Object> AddProperty(
+ MUST_USE_RESULT static MaybeHandle<Object> AddProperty(
Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK,
ValueType value_type = OPTIMAL_REPRESENTATION,
StoreMode mode = ALLOW_AS_CONSTANT,
TransitionFlag flag = INSERT_TRANSITION);
- // Add a constant function property to a fast-case object.
- // This leaves a CONSTANT_TRANSITION in the old map, and
- // if it is called on a second object with this map, a
- // normal property is added instead, with a map transition.
- // This avoids the creation of many maps with the same constant
- // function, all orphaned.
- static void AddConstantProperty(Handle<JSObject> object,
- Handle<Name> name,
- Handle<Object> constant,
- PropertyAttributes attributes,
- TransitionFlag flag);
-
// Add a property to a fast-case object.
static void AddFastProperty(Handle<JSObject> object,
Handle<Name> name,
@@ -2790,14 +2764,9 @@ class JSObject: public JSReceiver {
ValueType value_type,
TransitionFlag flag);
- // Add a property to a fast-case object using a map transition to
- // new_map.
- static void AddFastPropertyUsingMap(Handle<JSObject> object,
- Handle<Map> new_map,
- Handle<Name> name,
- Handle<Object> value,
- int field_index,
- Representation representation);
+ static void MigrateToNewProperty(Handle<JSObject> object,
+ Handle<Map> transition,
+ Handle<Object> value);
// Add a property to a slow-case object.
static void AddSlowProperty(Handle<JSObject> object,
@@ -2805,25 +2774,29 @@ class JSObject: public JSReceiver {
Handle<Object> value,
PropertyAttributes attributes);
- static Handle<Object> DeleteProperty(Handle<JSObject> object,
- Handle<Name> name,
- DeleteMode mode);
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteProperty(
+ Handle<JSObject> object,
+ Handle<Name> name,
+ DeleteMode mode);
static Handle<Object> DeletePropertyPostInterceptor(Handle<JSObject> object,
Handle<Name> name,
DeleteMode mode);
- static Handle<Object> DeletePropertyWithInterceptor(Handle<JSObject> object,
- Handle<Name> name);
+ MUST_USE_RESULT static MaybeHandle<Object> DeletePropertyWithInterceptor(
+ Handle<JSObject> object,
+ Handle<Name> name);
// Deletes the named property in a normalized object.
static Handle<Object> DeleteNormalizedProperty(Handle<JSObject> object,
Handle<Name> name,
DeleteMode mode);
- static Handle<Object> DeleteElement(Handle<JSObject> object,
- uint32_t index,
- DeleteMode mode);
- static Handle<Object> DeleteElementWithInterceptor(Handle<JSObject> object,
- uint32_t index);
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteElement(
+ Handle<JSObject> object,
+ uint32_t index,
+ DeleteMode mode);
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteElementWithInterceptor(
+ Handle<JSObject> object,
+ uint32_t index);
bool ReferencesObjectFromElements(FixedArray* elements,
ElementsKind kind,
@@ -2835,7 +2808,7 @@ class JSObject: public JSReceiver {
// Gets the current elements capacity and the number of used elements.
void GetElementsCapacityAndUsage(int* capacity, int* used);
- bool CanSetCallback(Name* name);
+ static bool CanSetCallback(Handle<JSObject> object, Handle<Name> name);
static void SetElementCallback(Handle<JSObject> object,
uint32_t index,
Handle<Object> structure,
@@ -2885,7 +2858,7 @@ class JSObject: public JSReceiver {
MUST_USE_RESULT Object* GetIdentityHash();
- static Handle<Object> GetOrCreateIdentityHash(Handle<JSObject> object);
+ static Handle<Smi> GetOrCreateIdentityHash(Handle<JSObject> object);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
};
@@ -2899,6 +2872,10 @@ class FixedArrayBase: public HeapObject {
inline int length();
inline void set_length(int value);
+ // Get and set the length using acquire loads and release stores.
+ inline int synchronized_length();
+ inline void synchronized_set_length(int value);
+
inline static FixedArrayBase* cast(Object* object);
// Layout description.
@@ -2917,6 +2894,7 @@ class FixedArray: public FixedArrayBase {
public:
// Setter and getter for elements.
inline Object* get(int index);
+ static inline Handle<Object> get(Handle<FixedArray> array, int index);
// Setter that uses write barrier.
inline void set(int index, Object* value);
inline bool is_the_hole(int index);
@@ -2937,16 +2915,26 @@ class FixedArray: public FixedArrayBase {
// 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,
- PretenureFlag pretenure = NOT_TENURED);
+ inline void FillWithHoles(int from, int to);
+
+ // Shrink length and insert filler objects.
+ void Shrink(int length);
+
+ // Copy operation.
+ static Handle<FixedArray> CopySize(Handle<FixedArray> array,
+ int new_length,
+ PretenureFlag pretenure = NOT_TENURED);
// Add the elements of a JSArray to this FixedArray.
- MUST_USE_RESULT MaybeObject* AddKeysFromJSArray(JSArray* array);
+ MUST_USE_RESULT static MaybeHandle<FixedArray> AddKeysFromArrayLike(
+ Handle<FixedArray> content,
+ Handle<JSObject> array);
- // Compute the union of this and other.
- MUST_USE_RESULT MaybeObject* UnionOfKeys(FixedArray* other);
+ // Computes the union of keys and return the result.
+ // Used for implementing "for (n in object) { }"
+ MUST_USE_RESULT static MaybeHandle<FixedArray> UnionOfKeys(
+ Handle<FixedArray> first,
+ Handle<FixedArray> second);
// Copy a sub array from the receiver to dest.
void CopyTo(int pos, FixedArray* dest, int dest_pos, int len);
@@ -2957,6 +2945,11 @@ class FixedArray: public FixedArrayBase {
// Code Generation support.
static int OffsetOfElementAt(int index) { return SizeFor(index); }
+ // Garbage collection support.
+ Object** RawFieldOfElementAt(int index) {
+ return HeapObject::RawField(this, OffsetOfElementAt(index));
+ }
+
// Casting.
static inline FixedArray* cast(Object* obj);
@@ -3007,7 +3000,7 @@ class FixedArray: public FixedArrayBase {
Object* value);
private:
- STATIC_CHECK(kHeaderSize == Internals::kFixedArrayHeaderSize);
+ STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
};
@@ -3019,16 +3012,13 @@ class FixedDoubleArray: public FixedArrayBase {
// Setter and getter for elements.
inline double get_scalar(int index);
inline int64_t get_representation(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<FixedDoubleArray> array, int index);
inline void set(int index, double value);
inline void set_the_hole(int index);
// Checking for the hole.
inline bool is_the_hole(int index);
- // Copy operations
- MUST_USE_RESULT inline MaybeObject* Copy();
-
// Garbage collection support.
inline static int SizeFor(int length) {
return kHeaderSize + length * kDoubleSize;
@@ -3037,6 +3027,8 @@ class FixedDoubleArray: public FixedArrayBase {
// Gives access to raw memory which stores the array's data.
inline double* data_start();
+ inline void FillWithHoles(int from, int to);
+
// Code Generation support.
static int OffsetOfElementAt(int index) { return SizeFor(index); }
@@ -3064,75 +3056,277 @@ class FixedDoubleArray: public FixedArrayBase {
// ConstantPoolArray describes a fixed-sized array containing constant pool
-// entires.
-// The format of the pool is:
-// [0]: Field holding the first index which is a pointer entry
-// [1]: Field holding the first index which is a int32 entry
-// [2] ... [first_ptr_index() - 1]: 64 bit entries
-// [first_ptr_index()] ... [first_int32_index() - 1]: pointer entries
-// [first_int32_index()] ... [length - 1]: 32 bit entries
-class ConstantPoolArray: public FixedArrayBase {
- public:
- // Getters for the field storing the first index for different type entries.
- inline int first_ptr_index();
- inline int first_int64_index();
- inline int first_int32_index();
-
- // Getters for counts of different type entries.
- inline int count_of_ptr_entries();
- inline int count_of_int64_entries();
- inline int count_of_int32_entries();
+// entries.
+//
+// A ConstantPoolArray can be structured in two different ways depending upon
+// whether it is extended or small. The is_extended_layout() method can be used
+// to discover which layout the constant pool has.
+//
+// The format of a small constant pool is:
+// [kSmallLayout1Offset] : Small section layout bitmap 1
+// [kSmallLayout2Offset] : Small section layout bitmap 2
+// [first_index(INT64, SMALL_SECTION)] : 64 bit entries
+// ... : ...
+// [first_index(CODE_PTR, SMALL_SECTION)] : code pointer entries
+// ... : ...
+// [first_index(HEAP_PTR, SMALL_SECTION)] : heap pointer entries
+// ... : ...
+// [first_index(INT32, SMALL_SECTION)] : 32 bit entries
+// ... : ...
+//
+// If the constant pool has an extended layout, the extended section constant
+// pool also contains an extended section, which has the following format at
+// location get_extended_section_header_offset():
+// [kExtendedInt64CountOffset] : count of extended 64 bit entries
+// [kExtendedCodePtrCountOffset] : count of extended code pointers
+// [kExtendedHeapPtrCountOffset] : count of extended heap pointers
+// [kExtendedInt32CountOffset] : count of extended 32 bit entries
+// [first_index(INT64, EXTENDED_SECTION)] : 64 bit entries
+// ... : ...
+// [first_index(CODE_PTR, EXTENDED_SECTION)]: code pointer entries
+// ... : ...
+// [first_index(HEAP_PTR, EXTENDED_SECTION)]: heap pointer entries
+// ... : ...
+// [first_index(INT32, EXTENDED_SECTION)] : 32 bit entries
+// ... : ...
+//
+class ConstantPoolArray: public HeapObject {
+ public:
+ enum WeakObjectState {
+ NO_WEAK_OBJECTS,
+ WEAK_OBJECTS_IN_OPTIMIZED_CODE,
+ WEAK_OBJECTS_IN_IC
+ };
+
+ enum Type {
+ INT64 = 0,
+ CODE_PTR,
+ HEAP_PTR,
+ INT32,
+ // Number of types stored by the ConstantPoolArrays.
+ NUMBER_OF_TYPES,
+ FIRST_TYPE = INT64,
+ LAST_TYPE = INT32
+ };
+
+ enum LayoutSection {
+ SMALL_SECTION = 0,
+ EXTENDED_SECTION
+ };
+
+ class NumberOfEntries BASE_EMBEDDED {
+ public:
+ inline NumberOfEntries(int int64_count, int code_ptr_count,
+ int heap_ptr_count, int int32_count) {
+ element_counts_[INT64] = int64_count;
+ element_counts_[CODE_PTR] = code_ptr_count;
+ element_counts_[HEAP_PTR] = heap_ptr_count;
+ element_counts_[INT32] = int32_count;
+ }
+
+ inline NumberOfEntries(ConstantPoolArray* array, LayoutSection section) {
+ element_counts_[INT64] = array->number_of_entries(INT64, section);
+ element_counts_[CODE_PTR] = array->number_of_entries(CODE_PTR, section);
+ element_counts_[HEAP_PTR] = array->number_of_entries(HEAP_PTR, section);
+ element_counts_[INT32] = array->number_of_entries(INT32, section);
+ }
+
+ inline int count_of(Type type) const {
+ ASSERT(type < NUMBER_OF_TYPES);
+ return element_counts_[type];
+ }
+
+ inline int total_count() const {
+ int count = 0;
+ for (int i = 0; i < NUMBER_OF_TYPES; i++) {
+ count += element_counts_[i];
+ }
+ return count;
+ }
+
+ inline int are_in_range(int min, int max) const {
+ for (int i = FIRST_TYPE; i < NUMBER_OF_TYPES; i++) {
+ if (element_counts_[i] < min || element_counts_[i] > max) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private:
+ int element_counts_[NUMBER_OF_TYPES];
+ };
+
+ class Iterator BASE_EMBEDDED {
+ public:
+ inline Iterator(ConstantPoolArray* array, Type type)
+ : array_(array), type_(type), final_section_(array->final_section()) {
+ current_section_ = SMALL_SECTION;
+ next_index_ = array->first_index(type, SMALL_SECTION);
+ update_section();
+ }
+
+ inline int next_index();
+ inline bool is_finished();
+ private:
+ inline void update_section();
+ ConstantPoolArray* array_;
+ const Type type_;
+ const LayoutSection final_section_;
+
+ LayoutSection current_section_;
+ int next_index_;
+ };
+
+ // Getters for the first index, the last index and the count of entries of
+ // a given type for a given layout section.
+ inline int first_index(Type type, LayoutSection layout_section);
+ inline int last_index(Type type, LayoutSection layout_section);
+ inline int number_of_entries(Type type, LayoutSection layout_section);
+
+ // Returns the type of the entry at the given index.
+ inline Type get_type(int index);
// Setter and getter for pool elements.
- inline Object* get_ptr_entry(int index);
+ inline Address get_code_ptr_entry(int index);
+ inline Object* get_heap_ptr_entry(int index);
inline int64_t get_int64_entry(int index);
inline int32_t get_int32_entry(int index);
inline double get_int64_entry_as_double(int index);
+ inline void set(int index, Address value);
inline void set(int index, Object* value);
inline void set(int index, int64_t value);
inline void set(int index, double value);
inline void set(int index, int32_t value);
- // Set up initial state.
- inline void SetEntryCounts(int number_of_int64_entries,
- int number_of_ptr_entries,
- int number_of_int32_entries);
+ // Setter and getter for weak objects state
+ inline void set_weak_object_state(WeakObjectState state);
+ inline WeakObjectState get_weak_object_state();
+
+ // Returns true if the constant pool has an extended layout, false if it has
+ // only the small layout.
+ inline bool is_extended_layout();
- // Copy operations
- MUST_USE_RESULT inline MaybeObject* Copy();
+ // Returns the last LayoutSection in this constant pool array.
+ inline LayoutSection final_section();
+
+ // Set up initial state for a small layout constant pool array.
+ inline void Init(const NumberOfEntries& small);
+
+ // Set up initial state for an extended layout constant pool array.
+ inline void InitExtended(const NumberOfEntries& small,
+ const NumberOfEntries& extended);
+
+ // Clears the pointer entries with GC safe values.
+ void ClearPtrEntries(Isolate* isolate);
+
+ // returns the total number of entries in the constant pool array.
+ inline int length();
// Garbage collection support.
- inline static int SizeFor(int number_of_int64_entries,
- int number_of_ptr_entries,
- int number_of_int32_entries) {
- return RoundUp(OffsetAt(number_of_int64_entries,
- number_of_ptr_entries,
- number_of_int32_entries),
- kPointerSize);
+ inline int size();
+
+ inline static int SizeFor(const NumberOfEntries& small) {
+ int size = kFirstEntryOffset +
+ (small.count_of(INT64) * kInt64Size) +
+ (small.count_of(CODE_PTR) * kPointerSize) +
+ (small.count_of(HEAP_PTR) * kPointerSize) +
+ (small.count_of(INT32) * kInt32Size);
+ return RoundUp(size, kPointerSize);
+ }
+
+ inline static int SizeForExtended(const NumberOfEntries& small,
+ const NumberOfEntries& extended) {
+ int size = SizeFor(small);
+ size = RoundUp(size, kInt64Size); // Align extended header to 64 bits.
+ size += kExtendedFirstOffset +
+ (extended.count_of(INT64) * kInt64Size) +
+ (extended.count_of(CODE_PTR) * kPointerSize) +
+ (extended.count_of(HEAP_PTR) * kPointerSize) +
+ (extended.count_of(INT32) * kInt32Size);
+ return RoundUp(size, kPointerSize);
+ }
+
+ inline static int entry_size(Type type) {
+ switch (type) {
+ case INT32:
+ return kInt32Size;
+ case INT64:
+ return kInt64Size;
+ case CODE_PTR:
+ case HEAP_PTR:
+ return kPointerSize;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
}
// Code Generation support.
inline int OffsetOfElementAt(int index) {
- ASSERT(index < length());
- if (index >= first_int32_index()) {
- return OffsetAt(count_of_int64_entries(), count_of_ptr_entries(),
- index - first_int32_index());
- } else if (index >= first_ptr_index()) {
- return OffsetAt(count_of_int64_entries(), index - first_ptr_index(), 0);
+ int offset;
+ LayoutSection section;
+ if (is_extended_layout() && index >= first_extended_section_index()) {
+ section = EXTENDED_SECTION;
+ offset = get_extended_section_header_offset() + kExtendedFirstOffset;
} else {
- return OffsetAt(index, 0, 0);
+ section = SMALL_SECTION;
+ offset = kFirstEntryOffset;
}
+
+ // Add offsets for the preceding type sections.
+ ASSERT(index <= last_index(LAST_TYPE, section));
+ for (Type type = FIRST_TYPE; index > last_index(type, section);
+ type = next_type(type)) {
+ offset += entry_size(type) * number_of_entries(type, section);
+ }
+
+ // Add offset for the index in it's type.
+ Type type = get_type(index);
+ offset += entry_size(type) * (index - first_index(type, section));
+ return offset;
}
// Casting.
static inline ConstantPoolArray* cast(Object* obj);
- // Layout description.
- static const int kFirstPointerIndexOffset = FixedArray::kHeaderSize;
- static const int kFirstInt32IndexOffset =
- kFirstPointerIndexOffset + kPointerSize;
- static const int kFirstOffset = kFirstInt32IndexOffset + kPointerSize;
+ // Garbage collection support.
+ Object** RawFieldOfElementAt(int index) {
+ return HeapObject::RawField(this, OffsetOfElementAt(index));
+ }
+
+ // Small Layout description.
+ static const int kSmallLayout1Offset = HeapObject::kHeaderSize;
+ static const int kSmallLayout2Offset = kSmallLayout1Offset + kInt32Size;
+ static const int kHeaderSize = kSmallLayout2Offset + kInt32Size;
+ static const int kFirstEntryOffset = ROUND_UP(kHeaderSize, kInt64Size);
+
+ static const int kSmallLayoutCountBits = 10;
+ static const int kMaxSmallEntriesPerType = (1 << kSmallLayoutCountBits) - 1;
+
+ // Fields in kSmallLayout1Offset.
+ class Int64CountField: public BitField<int, 1, kSmallLayoutCountBits> {};
+ class CodePtrCountField: public BitField<int, 11, kSmallLayoutCountBits> {};
+ class HeapPtrCountField: public BitField<int, 21, kSmallLayoutCountBits> {};
+ class IsExtendedField: public BitField<bool, 31, 1> {};
+
+ // Fields in kSmallLayout2Offset.
+ class Int32CountField: public BitField<int, 1, kSmallLayoutCountBits> {};
+ class TotalCountField: public BitField<int, 11, 12> {};
+ class WeakObjectStateField: public BitField<WeakObjectState, 23, 2> {};
+
+ // Extended layout description, which starts at
+ // get_extended_section_header_offset().
+ static const int kExtendedInt64CountOffset = 0;
+ static const int kExtendedCodePtrCountOffset =
+ kExtendedInt64CountOffset + kPointerSize;
+ static const int kExtendedHeapPtrCountOffset =
+ kExtendedCodePtrCountOffset + kPointerSize;
+ static const int kExtendedInt32CountOffset =
+ kExtendedHeapPtrCountOffset + kPointerSize;
+ static const int kExtendedFirstOffset =
+ kExtendedInt32CountOffset + kPointerSize;
// Dispatched behavior.
void ConstantPoolIterateBody(ObjectVisitor* v);
@@ -3141,16 +3335,13 @@ class ConstantPoolArray: public FixedArrayBase {
DECLARE_VERIFIER(ConstantPoolArray)
private:
- inline void set_first_ptr_index(int value);
- inline void set_first_int32_index(int value);
+ inline int first_extended_section_index();
+ inline int get_extended_section_header_offset();
- inline static int OffsetAt(int number_of_int64_entries,
- int number_of_ptr_entries,
- int number_of_int32_entries) {
- return kFirstOffset
- + (number_of_int64_entries * kInt64Size)
- + (number_of_ptr_entries * kPointerSize)
- + (number_of_int32_entries * kInt32Size);
+ inline static Type next_type(Type type) {
+ ASSERT(type >= FIRST_TYPE && type < NUMBER_OF_TYPES);
+ int type_int = static_cast<int>(type);
+ return static_cast<Type>(++type_int);
}
DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolArray);
@@ -3167,23 +3358,6 @@ class ConstantPoolArray: public FixedArrayBase {
// [2 + number of descriptors * kDescriptorSize]: start of slack
class DescriptorArray: public FixedArray {
public:
- // WhitenessWitness is used to prove that a descriptor array is white
- // (unmarked), so incremental write barriers can be skipped because the
- // marking invariant cannot be broken and slots pointing into evacuation
- // candidates will be discovered when the object is scanned. A witness is
- // always stack-allocated right after creating an array. By allocating a
- // witness, incremental marking is globally disabled. The witness is then
- // passed along wherever needed to statically prove that the array is known to
- // be white.
- class WhitenessWitness {
- public:
- inline explicit WhitenessWitness(FixedArray* array);
- inline ~WhitenessWitness();
-
- private:
- IncrementalMarking* marking_;
- };
-
// Returns true for both shared empty_descriptor_array and for smis, which the
// map uses to encode additional bit fields when the descriptor array is not
// yet used.
@@ -3254,12 +3428,14 @@ class DescriptorArray: public FixedArray {
inline Name* GetKey(int descriptor_number);
inline Object** GetKeySlot(int descriptor_number);
inline Object* GetValue(int descriptor_number);
+ inline void SetValue(int descriptor_number, Object* value);
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);
+ inline HeapType* GetFieldType(int descriptor_number);
inline Object* GetConstant(int descriptor_number);
inline Object* GetCallbacksObject(int descriptor_number);
inline AccessorDescriptor* GetCallbacks(int descriptor_number);
@@ -3267,59 +3443,28 @@ class DescriptorArray: public FixedArray {
inline Name* GetSortedKey(int descriptor_number);
inline int GetSortedKeyIndex(int descriptor_number);
inline void SetSortedKey(int pointer, int descriptor_number);
- inline void InitializeRepresentations(Representation representation);
inline void SetRepresentation(int descriptor_number,
Representation representation);
// Accessor for complete descriptor.
inline void Get(int descriptor_number, Descriptor* desc);
- inline void Set(int descriptor_number,
- Descriptor* desc,
- const WhitenessWitness&);
inline void Set(int descriptor_number, Descriptor* desc);
+ void Replace(int descriptor_number, Descriptor* descriptor);
// Append automatically sets the enumeration index. This should only be used
// to add descriptors in bulk at the end, followed by sorting the descriptor
// array.
- inline void Append(Descriptor* desc, const WhitenessWitness&);
inline void Append(Descriptor* desc);
- // Transfer a complete descriptor from the src descriptor array to this
- // descriptor array.
- void CopyFrom(int dst_index,
- DescriptorArray* src,
- int src_index,
- const WhitenessWitness&);
- static Handle<DescriptorArray> Merge(Handle<DescriptorArray> desc,
- int verbatim,
- int valid,
- int new_size,
- int modify_index,
- StoreMode store_mode,
- Handle<DescriptorArray> other);
- MUST_USE_RESULT MaybeObject* Merge(int verbatim,
- int valid,
- int new_size,
- int modify_index,
- StoreMode store_mode,
- DescriptorArray* other);
-
- bool IsMoreGeneralThan(int verbatim,
- int valid,
- int new_size,
- DescriptorArray* other);
-
- MUST_USE_RESULT MaybeObject* CopyUpTo(int enumeration_index) {
- return CopyUpToAddAttributes(enumeration_index, NONE);
- }
+ static Handle<DescriptorArray> CopyUpTo(Handle<DescriptorArray> desc,
+ int enumeration_index,
+ int slack = 0);
static Handle<DescriptorArray> CopyUpToAddAttributes(
Handle<DescriptorArray> desc,
int enumeration_index,
- PropertyAttributes attributes);
- MUST_USE_RESULT MaybeObject* CopyUpToAddAttributes(
- int enumeration_index,
- PropertyAttributes attributes);
+ PropertyAttributes attributes,
+ int slack = 0);
// Sort the instance descriptors by the hash codes of their keys.
void Sort();
@@ -3333,9 +3478,9 @@ class DescriptorArray: public FixedArray {
// Allocates a DescriptorArray, but returns the singleton
// empty descriptor array object if number_of_descriptors is 0.
- MUST_USE_RESULT static MaybeObject* Allocate(Isolate* isolate,
- int number_of_descriptors,
- int slack = 0);
+ static Handle<DescriptorArray> Allocate(Isolate* isolate,
+ int number_of_descriptors,
+ int slack = 0);
// Casting.
static inline DescriptorArray* cast(Object* obj);
@@ -3389,6 +3534,23 @@ class DescriptorArray: public FixedArray {
}
private:
+ // WhitenessWitness is used to prove that a descriptor array is white
+ // (unmarked), so incremental write barriers can be skipped because the
+ // marking invariant cannot be broken and slots pointing into evacuation
+ // candidates will be discovered when the object is scanned. A witness is
+ // always stack-allocated right after creating an array. By allocating a
+ // witness, incremental marking is globally disabled. The witness is then
+ // passed along wherever needed to statically prove that the array is known to
+ // be white.
+ class WhitenessWitness {
+ public:
+ inline explicit WhitenessWitness(DescriptorArray* array);
+ inline ~WhitenessWitness();
+
+ private:
+ IncrementalMarking* marking_;
+ };
+
// An entry in a DescriptorArray, represented as an (array, index) pair.
class Entry {
public:
@@ -3422,6 +3584,18 @@ class DescriptorArray: public FixedArray {
kDescriptorValue;
}
+ // Transfer a complete descriptor from the src descriptor array to this
+ // descriptor array.
+ void CopyFrom(int index,
+ DescriptorArray* src,
+ const WhitenessWitness&);
+
+ inline void Set(int descriptor_number,
+ Descriptor* desc,
+ const WhitenessWitness&);
+
+ inline void Append(Descriptor* desc, const WhitenessWitness&);
+
// Swap first and second descriptor.
inline void SwapSortedKeys(int first, int second);
@@ -3461,7 +3635,7 @@ inline int Search(T* array, Name* 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(Heap* heap, Key key);
+// static inline Handle<Object> AsHandle(Isolate* isolate, Key key);
// // The prefix size indicates number of elements in the beginning
// // of the backing storage.
// static const int kPrefixSize = ..;
@@ -3488,14 +3662,13 @@ class BaseShape {
}
};
-template<typename Shape, typename Key>
+template<typename Derived, typename Shape, typename Key>
class HashTable: public FixedArray {
public:
// Wrapper methods
inline uint32_t Hash(Key key) {
if (Shape::UsesSeed) {
- return Shape::SeededHash(key,
- GetHeap()->HashSeed());
+ return Shape::SeededHash(key, GetHeap()->HashSeed());
} else {
return Shape::Hash(key);
}
@@ -3503,8 +3676,7 @@ class HashTable: public FixedArray {
inline uint32_t HashForObject(Key key, Object* object) {
if (Shape::UsesSeed) {
- return Shape::SeededHashForObject(key,
- GetHeap()->HashSeed(), object);
+ return Shape::SeededHashForObject(key, GetHeap()->HashSeed(), object);
} else {
return Shape::HashForObject(key, object);
}
@@ -3540,9 +3712,9 @@ class HashTable: public FixedArray {
SetNumberOfDeletedElements(NumberOfDeletedElements() + n);
}
- // Returns a new HashTable object. Might return Failure.
- MUST_USE_RESULT static MaybeObject* Allocate(
- Heap* heap,
+ // Returns a new HashTable object.
+ MUST_USE_RESULT static Handle<Derived> New(
+ Isolate* isolate,
int at_least_space_for,
MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
PretenureFlag pretenure = NOT_TENURED);
@@ -3601,7 +3773,6 @@ class HashTable: public FixedArray {
void Rehash(Key key);
protected:
- friend class ObjectHashSet;
friend class ObjectHashTable;
// Find the entry at which to insert element with the given key that
@@ -3649,6 +3820,17 @@ class HashTable: public FixedArray {
return (last + number) & (size - 1);
}
+ // Attempt to shrink hash table after removal of key.
+ MUST_USE_RESULT static Handle<Derived> Shrink(Handle<Derived> table, Key key);
+
+ // Ensure enough space for n additional elements.
+ MUST_USE_RESULT static Handle<Derived> EnsureCapacity(
+ Handle<Derived> table,
+ int n,
+ Key key,
+ PretenureFlag pretenure = NOT_TENURED);
+
+ private:
// Returns _expected_ if one of entries given by the first _probe_ probes is
// equal to _expected_. Otherwise, returns the entry given by the probe
// number _probe_.
@@ -3657,16 +3839,7 @@ class HashTable: public FixedArray {
void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode);
// Rehashes this hash-table into the new table.
- MUST_USE_RESULT MaybeObject* Rehash(HashTable* new_table, Key key);
-
- // Attempt to shrink hash table after removal of key.
- MUST_USE_RESULT MaybeObject* Shrink(Key key);
-
- // Ensure enough space for n additional elements.
- MUST_USE_RESULT MaybeObject* EnsureCapacity(
- int n,
- Key key,
- PretenureFlag pretenure = NOT_TENURED);
+ void Rehash(Handle<Derived> new_table, Key key);
};
@@ -3680,8 +3853,7 @@ class HashTableKey {
// Returns the hash value for object.
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(Heap* heap) = 0;
+ MUST_USE_RESULT virtual Handle<Object> AsHandle(Isolate* isolate) = 0;
// Required.
virtual ~HashTableKey() {}
};
@@ -3692,16 +3864,16 @@ class StringTableShape : public BaseShape<HashTableKey*> {
static inline bool IsMatch(HashTableKey* key, Object* value) {
return key->IsMatch(value);
}
+
static inline uint32_t Hash(HashTableKey* key) {
return key->Hash();
}
+
static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
return key->HashForObject(object);
}
- MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
- HashTableKey* key) {
- return key->AsObject(heap);
- }
+
+ static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
static const int kPrefixSize = 0;
static const int kEntrySize = 1;
@@ -3713,40 +3885,35 @@ class SeqOneByteString;
//
// No special elements in the prefix and the element size is 1
// because only the string itself (the key) needs to be stored.
-class StringTable: public HashTable<StringTableShape, HashTableKey*> {
- public:
- // 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* LookupTwoByteString(
- Vector<const uc16> str,
- Object** s);
- MUST_USE_RESULT MaybeObject* LookupString(String* key, Object** s);
+class StringTable: public HashTable<StringTable,
+ StringTableShape,
+ HashTableKey*> {
+ public:
+ // Find string in the string table. If it is not there yet, it is
+ // added. The return value is the string found.
+ static Handle<String> LookupString(Isolate* isolate, Handle<String> key);
+ static Handle<String> LookupKey(Isolate* isolate, HashTableKey* key);
+
+ // Tries to internalize given string and returns string handle on success
+ // or an empty handle otherwise.
+ MUST_USE_RESULT static MaybeHandle<String> InternalizeStringIfExists(
+ Isolate* isolate,
+ Handle<String> string);
// 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 LookupStringIfExists(String* str, String** result);
- bool LookupTwoCharsStringIfExists(uint16_t c1, uint16_t c2, String** result);
+ // string handle if it is found, or an empty handle otherwise.
+ MUST_USE_RESULT static MaybeHandle<String> LookupStringIfExists(
+ Isolate* isolate,
+ Handle<String> str);
+ MUST_USE_RESULT static MaybeHandle<String> LookupTwoCharsStringIfExists(
+ Isolate* isolate,
+ uint16_t c1,
+ uint16_t c2);
// Casting.
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(StringTable);
@@ -3758,6 +3925,7 @@ class MapCacheShape : public BaseShape<HashTableKey*> {
static inline bool IsMatch(HashTableKey* key, Object* value) {
return key->IsMatch(value);
}
+
static inline uint32_t Hash(HashTableKey* key) {
return key->Hash();
}
@@ -3766,10 +3934,7 @@ class MapCacheShape : public BaseShape<HashTableKey*> {
return key->HashForObject(object);
}
- MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
- HashTableKey* key) {
- return key->AsObject(heap);
- }
+ static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
static const int kPrefixSize = 0;
static const int kEntrySize = 2;
@@ -3780,11 +3945,12 @@ class MapCacheShape : public BaseShape<HashTableKey*> {
//
// 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*> {
+class MapCache: public HashTable<MapCache, MapCacheShape, HashTableKey*> {
public:
// Find cached value for a name key, otherwise return null.
Object* Lookup(FixedArray* key);
- MUST_USE_RESULT MaybeObject* Put(FixedArray* key, Map* value);
+ static Handle<MapCache> Put(
+ Handle<MapCache> map_cache, Handle<FixedArray> key, Handle<Map> value);
static inline MapCache* cast(Object* obj);
private:
@@ -3792,43 +3958,53 @@ class MapCache: public HashTable<MapCacheShape, HashTableKey*> {
};
-template <typename Shape, typename Key>
-class Dictionary: public HashTable<Shape, Key> {
+template <typename Derived, typename Shape, typename Key>
+class Dictionary: public HashTable<Derived, Shape, Key> {
+ protected:
+ typedef HashTable<Derived, Shape, Key> DerivedHashTable;
+
public:
- static inline Dictionary<Shape, Key>* cast(Object* obj) {
- return reinterpret_cast<Dictionary<Shape, Key>*>(obj);
+ static inline Dictionary* cast(Object* obj) {
+ return reinterpret_cast<Dictionary*>(obj);
}
// Returns the value at entry.
Object* ValueAt(int entry) {
- return this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 1);
+ return this->get(DerivedHashTable::EntryToIndex(entry) + 1);
}
// Set the value for entry.
void ValueAtPut(int entry, Object* value) {
- this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 1, value);
+ this->set(DerivedHashTable::EntryToIndex(entry) + 1, value);
}
// Returns the property details for the property at entry.
PropertyDetails DetailsAt(int entry) {
ASSERT(entry >= 0); // Not found is -1, which is not caught by get().
return PropertyDetails(
- Smi::cast(this->get(HashTable<Shape, Key>::EntryToIndex(entry) + 2)));
+ Smi::cast(this->get(DerivedHashTable::EntryToIndex(entry) + 2)));
}
// Set the details for entry.
void DetailsAtPut(int entry, PropertyDetails value) {
- this->set(HashTable<Shape, Key>::EntryToIndex(entry) + 2, value.AsSmi());
+ this->set(DerivedHashTable::EntryToIndex(entry) + 2, value.AsSmi());
}
// Sorting support
void CopyValuesTo(FixedArray* elements);
// Delete a property from the dictionary.
- Object* DeleteProperty(int entry, JSObject::DeleteMode mode);
+ static Handle<Object> DeleteProperty(
+ Handle<Derived> dictionary,
+ int entry,
+ JSObject::DeleteMode mode);
// Attempt to shrink the dictionary after deletion of key.
- MUST_USE_RESULT MaybeObject* Shrink(Key key);
+ MUST_USE_RESULT static inline Handle<Derived> Shrink(
+ Handle<Derived> dictionary,
+ Key key) {
+ return DerivedHashTable::Shrink(dictionary, key);
+ }
// Returns the number of elements in the dictionary filtering out properties
// with the specified attributes.
@@ -3855,17 +4031,17 @@ class Dictionary: public HashTable<Shape, Key> {
}
int NextEnumerationIndex() {
- return Smi::cast(FixedArray::get(kNextEnumerationIndexIndex))->value();
+ return Smi::cast(this->get(kNextEnumerationIndexIndex))->value();
}
- // Returns a new array for dictionary usage. Might return Failure.
- MUST_USE_RESULT static MaybeObject* Allocate(
- Heap* heap,
+ // Creates a new dictionary.
+ MUST_USE_RESULT static Handle<Derived> New(
+ Isolate* isolate,
int at_least_space_for,
PretenureFlag pretenure = NOT_TENURED);
// Ensure enough space for n additional elements.
- MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key);
+ static Handle<Derived> EnsureCapacity(Handle<Derived> obj, int n, Key key);
#ifdef OBJECT_PRINT
void Print(FILE* out = stdout);
@@ -3875,49 +4051,59 @@ class Dictionary: public HashTable<Shape, Key> {
// Sets the entry to (key, value) pair.
inline void SetEntry(int entry,
- Object* key,
- Object* value);
+ Handle<Object> key,
+ Handle<Object> value);
inline void SetEntry(int entry,
- Object* key,
- Object* value,
+ Handle<Object> key,
+ Handle<Object> value,
PropertyDetails details);
- MUST_USE_RESULT MaybeObject* Add(Key key,
- Object* value,
- PropertyDetails details);
+ MUST_USE_RESULT static Handle<Derived> Add(
+ Handle<Derived> dictionary,
+ Key key,
+ Handle<Object> value,
+ PropertyDetails details);
protected:
// Generic at put operation.
- MUST_USE_RESULT MaybeObject* AtPut(Key key, Object* value);
+ MUST_USE_RESULT static Handle<Derived> AtPut(
+ Handle<Derived> dictionary,
+ Key key,
+ Handle<Object> value);
// Add entry to dictionary.
- MUST_USE_RESULT MaybeObject* AddEntry(Key key,
- Object* value,
- PropertyDetails details,
- uint32_t hash);
+ static void AddEntry(
+ Handle<Derived> dictionary,
+ Key key,
+ Handle<Object> value,
+ PropertyDetails details,
+ uint32_t hash);
// Generate new enumeration indices to avoid enumeration index overflow.
- MUST_USE_RESULT MaybeObject* GenerateNewEnumerationIndices();
- static const int kMaxNumberKeyIndex =
- HashTable<Shape, Key>::kPrefixStartIndex;
+ static void GenerateNewEnumerationIndices(Handle<Derived> dictionary);
+ static const int kMaxNumberKeyIndex = DerivedHashTable::kPrefixStartIndex;
static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
};
-class NameDictionaryShape : public BaseShape<Name*> {
+class NameDictionaryShape : public BaseShape<Handle<Name> > {
public:
- 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 inline bool IsMatch(Handle<Name> key, Object* other);
+ static inline uint32_t Hash(Handle<Name> key);
+ static inline uint32_t HashForObject(Handle<Name> key, Object* object);
+ static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key);
static const int kPrefixSize = 2;
static const int kEntrySize = 3;
static const bool kIsEnumerable = true;
};
-class NameDictionary: public Dictionary<NameDictionaryShape, Name*> {
+class NameDictionary: public Dictionary<NameDictionary,
+ NameDictionaryShape,
+ Handle<Name> > {
+ typedef Dictionary<
+ NameDictionary, NameDictionaryShape, Handle<Name> > DerivedDictionary;
+
public:
static inline NameDictionary* cast(Object* obj) {
ASSERT(obj->IsDictionary());
@@ -3925,26 +4111,20 @@ class NameDictionary: public Dictionary<NameDictionaryShape, Name*> {
}
// Copies enumerable keys to preallocated fixed array.
- FixedArray* CopyEnumKeysTo(FixedArray* storage);
- static void DoGenerateNewEnumerationIndices(
+ void CopyEnumKeysTo(FixedArray* storage);
+ inline static void DoGenerateNewEnumerationIndices(
Handle<NameDictionary> dictionary);
- // For transforming properties of a JSObject.
- MUST_USE_RESULT MaybeObject* TransformPropertiesToFastFor(
- JSObject* obj,
- int unused_property_fields);
-
// Find entry for key, otherwise return kNotFound. Optimized version of
// HashTable::FindEntry.
- int FindEntry(Name* key);
+ int FindEntry(Handle<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(Heap* heap,
- uint32_t key);
+ static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
static const int kEntrySize = 3;
static const bool kIsEnumerable = false;
};
@@ -3972,7 +4152,9 @@ class UnseededNumberDictionaryShape : public NumberDictionaryShape {
class SeededNumberDictionary
- : public Dictionary<SeededNumberDictionaryShape, uint32_t> {
+ : public Dictionary<SeededNumberDictionary,
+ SeededNumberDictionaryShape,
+ uint32_t> {
public:
static SeededNumberDictionary* cast(Object* obj) {
ASSERT(obj->IsDictionary());
@@ -3980,28 +4162,24 @@ class SeededNumberDictionary
}
// Type specific at put (default NONE attributes is used when adding).
- MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value);
+ MUST_USE_RESULT static Handle<SeededNumberDictionary> AtNumberPut(
+ Handle<SeededNumberDictionary> dictionary,
+ uint32_t key,
+ Handle<Object> value);
MUST_USE_RESULT static Handle<SeededNumberDictionary> AddNumberEntry(
Handle<SeededNumberDictionary> dictionary,
uint32_t key,
Handle<Object> value,
PropertyDetails details);
- MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key,
- Object* value,
- PropertyDetails details);
// Set an existing entry or add a new one if needed.
// Return the updated dictionary.
MUST_USE_RESULT static Handle<SeededNumberDictionary> Set(
Handle<SeededNumberDictionary> dictionary,
- uint32_t index,
+ uint32_t key,
Handle<Object> value,
PropertyDetails details);
- MUST_USE_RESULT MaybeObject* Set(uint32_t key,
- Object* value,
- PropertyDetails details);
-
void UpdateMaxNumberKey(uint32_t key);
// If slow elements are required we will never go back to fast-case
@@ -4025,7 +4203,9 @@ class SeededNumberDictionary
class UnseededNumberDictionary
- : public Dictionary<UnseededNumberDictionaryShape, uint32_t> {
+ : public Dictionary<UnseededNumberDictionary,
+ UnseededNumberDictionaryShape,
+ uint32_t> {
public:
static UnseededNumberDictionary* cast(Object* obj) {
ASSERT(obj->IsDictionary());
@@ -4033,94 +4213,67 @@ class UnseededNumberDictionary
}
// Type specific at put (default NONE attributes is used when adding).
- MUST_USE_RESULT MaybeObject* AtNumberPut(uint32_t key, Object* value);
- MUST_USE_RESULT MaybeObject* AddNumberEntry(uint32_t key, Object* value);
+ MUST_USE_RESULT static Handle<UnseededNumberDictionary> AtNumberPut(
+ Handle<UnseededNumberDictionary> dictionary,
+ uint32_t key,
+ Handle<Object> value);
+ MUST_USE_RESULT static Handle<UnseededNumberDictionary> AddNumberEntry(
+ Handle<UnseededNumberDictionary> dictionary,
+ uint32_t key,
+ Handle<Object> value);
// Set an existing entry or add a new one if needed.
// Return the updated dictionary.
MUST_USE_RESULT static Handle<UnseededNumberDictionary> Set(
Handle<UnseededNumberDictionary> dictionary,
- uint32_t index,
+ uint32_t key,
Handle<Object> value);
-
- MUST_USE_RESULT MaybeObject* Set(uint32_t key, Object* value);
};
-template <int entrysize>
-class ObjectHashTableShape : public BaseShape<Object*> {
+class ObjectHashTableShape : public BaseShape<Handle<Object> > {
public:
- 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(Heap* heap,
- Object* key);
+ static inline bool IsMatch(Handle<Object> key, Object* other);
+ static inline uint32_t Hash(Handle<Object> key);
+ static inline uint32_t HashForObject(Handle<Object> key, Object* object);
+ static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
static const int kPrefixSize = 0;
- static const int kEntrySize = entrysize;
-};
-
-
-// ObjectHashSet holds keys that are arbitrary objects by using the identity
-// hash of the key for hashing purposes.
-class ObjectHashSet: public HashTable<ObjectHashTableShape<1>, Object*> {
- public:
- static inline ObjectHashSet* cast(Object* obj) {
- ASSERT(obj->IsHashTable());
- return reinterpret_cast<ObjectHashSet*>(obj);
- }
-
- // Looks up whether the given key is part of this hash set.
- bool Contains(Object* key);
-
- static Handle<ObjectHashSet> EnsureCapacity(
- Handle<ObjectHashSet> table,
- int n,
- Handle<Object> key,
- PretenureFlag pretenure = NOT_TENURED);
-
- // Attempt to shrink hash table after removal of key.
- static Handle<ObjectHashSet> Shrink(Handle<ObjectHashSet> table,
- Handle<Object> key);
-
- // Adds the given key to this hash set.
- static Handle<ObjectHashSet> Add(Handle<ObjectHashSet> table,
- Handle<Object> key);
-
- // Removes the given key from this hash set.
- static Handle<ObjectHashSet> Remove(Handle<ObjectHashSet> table,
- Handle<Object> key);
+ static const int kEntrySize = 2;
};
// ObjectHashTable maps keys that are arbitrary objects to object values by
// using the identity hash of the key for hashing purposes.
-class ObjectHashTable: public HashTable<ObjectHashTableShape<2>, Object*> {
+class ObjectHashTable: public HashTable<ObjectHashTable,
+ ObjectHashTableShape,
+ Handle<Object> > {
+ typedef HashTable<
+ ObjectHashTable, ObjectHashTableShape, Handle<Object> > DerivedHashTable;
public:
static inline ObjectHashTable* cast(Object* obj) {
ASSERT(obj->IsHashTable());
return reinterpret_cast<ObjectHashTable*>(obj);
}
- static Handle<ObjectHashTable> EnsureCapacity(
- Handle<ObjectHashTable> table,
- int n,
- Handle<Object> key,
- PretenureFlag pretenure = NOT_TENURED);
-
// Attempt to shrink hash table after removal of key.
- static Handle<ObjectHashTable> Shrink(Handle<ObjectHashTable> table,
- Handle<Object> key);
+ MUST_USE_RESULT static inline Handle<ObjectHashTable> Shrink(
+ Handle<ObjectHashTable> table,
+ Handle<Object> key);
// Looks up the value associated with the given key. The hole value is
// returned in case the key is not present.
- Object* Lookup(Object* key);
+ Object* Lookup(Handle<Object> key);
- // Adds (or overwrites) the value associated with the given key. Mapping a
- // key to the hole value causes removal of the whole entry.
+ // Adds (or overwrites) the value associated with the given key.
static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
Handle<Object> key,
Handle<Object> value);
+ // Returns an ObjectHashTable (possibly |table|) where |key| has been removed.
+ static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
+ Handle<Object> key,
+ bool* was_present);
+
private:
friend class MarkCompactCollector;
@@ -4134,14 +4287,225 @@ class ObjectHashTable: public HashTable<ObjectHashTableShape<2>, Object*> {
};
+// OrderedHashTable is a HashTable with Object keys that preserves
+// insertion order. There are Map and Set interfaces (OrderedHashMap
+// and OrderedHashTable, below). It is meant to be used by JSMap/JSSet.
+//
+// Only Object* keys are supported, with Object::SameValueZero() used as the
+// equality operator and Object::GetHash() for the hash function.
+//
+// Based on the "Deterministic Hash Table" as described by Jason Orendorff at
+// https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables
+// Originally attributed to Tyler Close.
+//
+// Memory layout:
+// [0]: bucket count
+// [1]: element count
+// [2]: deleted element count
+// [3..(3 + NumberOfBuckets() - 1)]: "hash table", where each item is an
+// offset into the data table (see below) where the
+// first item in this bucket is stored.
+// [3 + NumberOfBuckets()..length]: "data table", an array of length
+// Capacity() * kEntrySize, where the first entrysize
+// items are handled by the derived class and the
+// item at kChainOffset is another entry into the
+// data table indicating the next entry in this hash
+// bucket.
+//
+// When we transition the table to a new version we obsolete it and reuse parts
+// of the memory to store information how to transition an iterator to the new
+// table:
+//
+// Memory layout for obsolete table:
+// [0]: bucket count
+// [1]: Next newer table
+// [2]: Number of removed holes or -1 when the table was cleared.
+// [3..(3 + NumberOfRemovedHoles() - 1)]: The indexes of the removed holes.
+// [3 + NumberOfRemovedHoles()..length]: Not used
+//
+template<class Derived, class Iterator, int entrysize>
+class OrderedHashTable: public FixedArray {
+ public:
+ // Returns an OrderedHashTable with a capacity of at least |capacity|.
+ static Handle<Derived> Allocate(
+ Isolate* isolate, int capacity, PretenureFlag pretenure = NOT_TENURED);
+
+ // Returns an OrderedHashTable (possibly |table|) with enough space
+ // to add at least one new element.
+ static Handle<Derived> EnsureGrowable(Handle<Derived> table);
+
+ // Returns an OrderedHashTable (possibly |table|) that's shrunken
+ // if possible.
+ static Handle<Derived> Shrink(Handle<Derived> table);
+
+ // Returns a new empty OrderedHashTable and records the clearing so that
+ // exisiting iterators can be updated.
+ static Handle<Derived> Clear(Handle<Derived> table);
+
+ // Returns an OrderedHashTable (possibly |table|) where |key| has been
+ // removed.
+ static Handle<Derived> Remove(Handle<Derived> table, Handle<Object> key,
+ bool* was_present);
+
+ // Returns kNotFound if the key isn't present.
+ int FindEntry(Handle<Object> key);
+
+ int NumberOfElements() {
+ return Smi::cast(get(kNumberOfElementsIndex))->value();
+ }
+
+ int NumberOfDeletedElements() {
+ return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
+ }
+
+ int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); }
+
+ int NumberOfBuckets() {
+ return Smi::cast(get(kNumberOfBucketsIndex))->value();
+ }
+
+ // Returns the index into the data table where the new entry
+ // should be placed. The table is assumed to have enough space
+ // for a new entry.
+ int AddEntry(int hash);
+
+ // Removes the entry, and puts the_hole in entrysize pointers
+ // (leaving the hash table chain intact).
+ void RemoveEntry(int entry);
+
+ // Returns an index into |this| for the given entry.
+ int EntryToIndex(int entry) {
+ return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize);
+ }
+
+ Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
+
+ bool IsObsolete() {
+ return !get(kNextTableIndex)->IsSmi();
+ }
+
+ // The next newer table. This is only valid if the table is obsolete.
+ Derived* NextTable() {
+ return Derived::cast(get(kNextTableIndex));
+ }
+
+ // When the table is obsolete we store the indexes of the removed holes.
+ int RemovedIndexAt(int index) {
+ return Smi::cast(get(kRemovedHolesIndex + index))->value();
+ }
+
+ static const int kNotFound = -1;
+ static const int kMinCapacity = 4;
+
+ private:
+ static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
+
+ void SetNumberOfBuckets(int num) {
+ set(kNumberOfBucketsIndex, Smi::FromInt(num));
+ }
+
+ void SetNumberOfElements(int num) {
+ set(kNumberOfElementsIndex, Smi::FromInt(num));
+ }
+
+ void SetNumberOfDeletedElements(int num) {
+ set(kNumberOfDeletedElementsIndex, Smi::FromInt(num));
+ }
+
+ int Capacity() {
+ return NumberOfBuckets() * kLoadFactor;
+ }
+
+ // Returns the next entry for the given entry.
+ int ChainAt(int entry) {
+ return Smi::cast(get(EntryToIndex(entry) + kChainOffset))->value();
+ }
+
+ int HashToBucket(int hash) {
+ return hash & (NumberOfBuckets() - 1);
+ }
+
+ int HashToEntry(int hash) {
+ int bucket = HashToBucket(hash);
+ return Smi::cast(get(kHashTableStartIndex + bucket))->value();
+ }
+
+ void SetNextTable(Derived* next_table) {
+ set(kNextTableIndex, next_table);
+ }
+
+ void SetRemovedIndexAt(int index, int removed_index) {
+ return set(kRemovedHolesIndex + index, Smi::FromInt(removed_index));
+ }
+
+ static const int kNumberOfBucketsIndex = 0;
+ static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
+ static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
+ static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1;
+
+ static const int kNextTableIndex = kNumberOfElementsIndex;
+ static const int kRemovedHolesIndex = kHashTableStartIndex;
+
+ static const int kEntrySize = entrysize + 1;
+ static const int kChainOffset = entrysize;
+
+ static const int kLoadFactor = 2;
+ static const int kMaxCapacity =
+ (FixedArray::kMaxLength - kHashTableStartIndex)
+ / (1 + (kEntrySize * kLoadFactor));
+};
+
+
+class JSSetIterator;
+
+
+class OrderedHashSet: public OrderedHashTable<
+ OrderedHashSet, JSSetIterator, 1> {
+ public:
+ static OrderedHashSet* cast(Object* obj) {
+ ASSERT(obj->IsOrderedHashTable());
+ return reinterpret_cast<OrderedHashSet*>(obj);
+ }
+
+ bool Contains(Handle<Object> key);
+ static Handle<OrderedHashSet> Add(
+ Handle<OrderedHashSet> table, Handle<Object> key);
+};
+
+
+class JSMapIterator;
+
+
+class OrderedHashMap:public OrderedHashTable<
+ OrderedHashMap, JSMapIterator, 2> {
+ public:
+ static OrderedHashMap* cast(Object* obj) {
+ ASSERT(obj->IsOrderedHashTable());
+ return reinterpret_cast<OrderedHashMap*>(obj);
+ }
+
+ Object* Lookup(Handle<Object> key);
+ static Handle<OrderedHashMap> Put(
+ Handle<OrderedHashMap> table,
+ Handle<Object> key,
+ Handle<Object> value);
+
+ private:
+ Object* ValueAt(int entry) {
+ return get(EntryToIndex(entry) + kValueOffset);
+ }
+
+ static const int kValueOffset = 1;
+};
+
+
template <int entrysize>
-class WeakHashTableShape : public BaseShape<Object*> {
+class WeakHashTableShape : public BaseShape<Handle<Object> > {
public:
- 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(Heap* heap,
- Object* key);
+ static inline bool IsMatch(Handle<Object> key, Object* other);
+ static inline uint32_t Hash(Handle<Object> key);
+ static inline uint32_t HashForObject(Handle<Object> key, Object* object);
+ static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Object> key);
static const int kPrefixSize = 0;
static const int kEntrySize = entrysize;
};
@@ -4150,7 +4514,11 @@ class WeakHashTableShape : public BaseShape<Object*> {
// WeakHashTable maps keys that are arbitrary objects to object values.
// It is used for the global weak hash table that maps objects
// embedded in optimized code to dependent code lists.
-class WeakHashTable: public HashTable<WeakHashTableShape<2>, Object*> {
+class WeakHashTable: public HashTable<WeakHashTable,
+ WeakHashTableShape<2>,
+ Handle<Object> > {
+ typedef HashTable<
+ WeakHashTable, WeakHashTableShape<2>, Handle<Object> > DerivedHashTable;
public:
static inline WeakHashTable* cast(Object* obj) {
ASSERT(obj->IsHashTable());
@@ -4159,11 +4527,13 @@ class WeakHashTable: public HashTable<WeakHashTableShape<2>, Object*> {
// Looks up the value associated with the given key. The hole value is
// returned in case the key is not present.
- Object* Lookup(Object* key);
+ Object* Lookup(Handle<Object> key);
// Adds (or overwrites) the value associated with the given key. Mapping a
// key to the hole value causes removal of the whole entry.
- MUST_USE_RESULT MaybeObject* Put(Object* key, Object* value);
+ MUST_USE_RESULT static Handle<WeakHashTable> Put(Handle<WeakHashTable> table,
+ Handle<Object> key,
+ Handle<Object> value);
// This function is called when heap verification is turned on.
void Zap(Object* value) {
@@ -4177,7 +4547,7 @@ class WeakHashTable: public HashTable<WeakHashTableShape<2>, Object*> {
private:
friend class MarkCompactCollector;
- void AddEntry(int entry, Object* key, Object* value);
+ void AddEntry(int entry, Handle<Object> key, Handle<Object> value);
// Returns the index to the value of an entry.
static inline int EntryToValueIndex(int entry) {
@@ -4239,13 +4609,11 @@ class ScopeInfo : public FixedArray {
// Does this scope call eval?
bool CallsEval();
- // Return the language mode of this scope.
- LanguageMode language_mode();
+ // Return the strict mode of this scope.
+ StrictMode strict_mode();
- // Does this scope make a non-strict eval call?
- bool CallsNonStrictEval() {
- return CallsEval() && (language_mode() == CLASSIC_MODE);
- }
+ // Does this scope make a sloppy eval call?
+ bool CallsSloppyEval() { return CallsEval() && strict_mode() == SLOPPY; }
// Return the total number of locals allocated on the stack and in the
// context. This includes the parameters that are allocated in the context.
@@ -4296,6 +4664,10 @@ class ScopeInfo : public FixedArray {
// Return the initialization flag of the given context local.
InitializationFlag ContextLocalInitFlag(int var);
+ // Return true if this local was introduced by the compiler, and should not be
+ // exposed to the user in a debugger.
+ bool LocalIsSynthetic(int var);
+
// 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 an internalized
@@ -4307,9 +4679,10 @@ class ScopeInfo : public FixedArray {
// 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,
- VariableMode* mode,
- InitializationFlag* init_flag);
+ static int ContextSlotIndex(Handle<ScopeInfo> scope_info,
+ Handle<String> name,
+ VariableMode* mode,
+ InitializationFlag* init_flag);
// Lookup support for serialized scope info. Returns the
// parameter index for a given parameter name if the parameter is present;
@@ -4419,9 +4792,9 @@ class ScopeInfo : public FixedArray {
// Properties of scopes.
class ScopeTypeField: public BitField<ScopeType, 0, 3> {};
class CallsEvalField: public BitField<bool, 3, 1> {};
- class LanguageModeField: public BitField<LanguageMode, 4, 2> {};
- class FunctionVariableField: public BitField<FunctionVariableInfo, 6, 2> {};
- class FunctionVariableMode: public BitField<VariableMode, 8, 3> {};
+ class StrictModeField: public BitField<StrictMode, 4, 1> {};
+ class FunctionVariableField: public BitField<FunctionVariableInfo, 5, 2> {};
+ class FunctionVariableMode: public BitField<VariableMode, 7, 3> {};
// BitFields representing the encoded information for context locals in the
// ContextLocalInfoEntries part.
@@ -4435,18 +4808,27 @@ class ScopeInfo : public FixedArray {
// needs very limited number of distinct normalized maps.
class NormalizedMapCache: public FixedArray {
public:
- static const int kEntries = 64;
+ static Handle<NormalizedMapCache> New(Isolate* isolate);
- static Handle<Map> Get(Handle<NormalizedMapCache> cache,
- Handle<JSObject> object,
- PropertyNormalizationMode mode);
+ MUST_USE_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
+ PropertyNormalizationMode mode);
+ void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
void Clear();
// Casting
static inline NormalizedMapCache* cast(Object* obj);
+ static inline bool IsNormalizedMapCache(Object* obj);
DECLARE_VERIFIER(NormalizedMapCache)
+ private:
+ static const int kEntries = 64;
+
+ static inline int GetIndex(Handle<Map> map);
+
+ // The following declarations hide base class methods.
+ Object* get(int index);
+ void set(int index, Object* value);
};
@@ -4513,6 +4895,9 @@ class FreeSpace: public HeapObject {
inline int size();
inline void set_size(int value);
+ inline int nobarrier_size();
+ inline void nobarrier_set_size(int value);
+
inline int Size() { return size(); }
// Casting.
@@ -4534,6 +4919,20 @@ class FreeSpace: public HeapObject {
};
+// V has parameters (Type, type, TYPE, C type, element_size)
+#define TYPED_ARRAYS(V) \
+ V(Uint8, uint8, UINT8, uint8_t, 1) \
+ V(Int8, int8, INT8, int8_t, 1) \
+ V(Uint16, uint16, UINT16, uint16_t, 2) \
+ V(Int16, int16, INT16, int16_t, 2) \
+ V(Uint32, uint32, UINT32, uint32_t, 4) \
+ V(Int32, int32, INT32, int32_t, 4) \
+ V(Float32, float32, FLOAT32, float, 4) \
+ V(Float64, float64, FLOAT64, double, 8) \
+ V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1)
+
+
+
// An ExternalArray represents a fixed-size array of primitive values
// which live outside the JavaScript heap. Its subclasses are used to
// implement the CanvasArray types being defined in the WebGL
@@ -4570,7 +4969,7 @@ class ExternalArray: public FixedArrayBase {
};
-// A ExternalPixelArray represents a fixed-size byte array with special
+// A ExternalUint8ClampedArray represents a fixed-size byte array with special
// semantics used for implementing the CanvasPixelArray object. Please see the
// specification at:
@@ -4578,247 +4977,315 @@ class ExternalArray: public FixedArrayBase {
// multipage/the-canvas-element.html#canvaspixelarray
// In particular, write access clamps the value written to 0 or 255 if the
// value written is outside this range.
-class ExternalPixelArray: public ExternalArray {
+class ExternalUint8ClampedArray: public ExternalArray {
public:
- inline uint8_t* external_pixel_pointer();
+ inline uint8_t* external_uint8_clamped_pointer();
// Setter and getter.
inline uint8_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalUint8ClampedArray> array,
+ int index);
inline void set(int index, uint8_t value);
- // This accessor applies the correct conversion from Smi, HeapNumber and
- // undefined and clamps the converted value between 0 and 255.
- Object* SetValue(uint32_t index, Object* value);
+ // This accessor applies the correct conversion from Smi, HeapNumber
+ // and undefined and clamps the converted value between 0 and 255.
+ static Handle<Object> SetValue(Handle<ExternalUint8ClampedArray> array,
+ uint32_t index,
+ Handle<Object> value);
// Casting.
- static inline ExternalPixelArray* cast(Object* obj);
+ static inline ExternalUint8ClampedArray* cast(Object* obj);
// Dispatched behavior.
- DECLARE_PRINTER(ExternalPixelArray)
- DECLARE_VERIFIER(ExternalPixelArray)
+ DECLARE_PRINTER(ExternalUint8ClampedArray)
+ DECLARE_VERIFIER(ExternalUint8ClampedArray)
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalPixelArray);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUint8ClampedArray);
};
-class ExternalByteArray: public ExternalArray {
+class ExternalInt8Array: public ExternalArray {
public:
// Setter and getter.
inline int8_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalInt8Array> array, int index);
inline void set(int index, int8_t value);
- static Handle<Object> SetValue(Handle<ExternalByteArray> array,
- uint32_t index,
- Handle<Object> value);
-
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
+ static Handle<Object> SetValue(Handle<ExternalInt8Array> array,
+ uint32_t index,
+ Handle<Object> value);
// Casting.
- static inline ExternalByteArray* cast(Object* obj);
+ static inline ExternalInt8Array* cast(Object* obj);
// Dispatched behavior.
- DECLARE_PRINTER(ExternalByteArray)
- DECLARE_VERIFIER(ExternalByteArray)
+ DECLARE_PRINTER(ExternalInt8Array)
+ DECLARE_VERIFIER(ExternalInt8Array)
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalByteArray);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalInt8Array);
};
-class ExternalUnsignedByteArray: public ExternalArray {
+class ExternalUint8Array: public ExternalArray {
public:
// Setter and getter.
inline uint8_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalUint8Array> array, int index);
inline void set(int index, uint8_t value);
- static Handle<Object> SetValue(Handle<ExternalUnsignedByteArray> array,
- uint32_t index,
- Handle<Object> value);
-
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
+ static Handle<Object> SetValue(Handle<ExternalUint8Array> array,
+ uint32_t index,
+ Handle<Object> value);
// Casting.
- static inline ExternalUnsignedByteArray* cast(Object* obj);
+ static inline ExternalUint8Array* cast(Object* obj);
// Dispatched behavior.
- DECLARE_PRINTER(ExternalUnsignedByteArray)
- DECLARE_VERIFIER(ExternalUnsignedByteArray)
+ DECLARE_PRINTER(ExternalUint8Array)
+ DECLARE_VERIFIER(ExternalUint8Array)
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedByteArray);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUint8Array);
};
-class ExternalShortArray: public ExternalArray {
+class ExternalInt16Array: public ExternalArray {
public:
// Setter and getter.
inline int16_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalInt16Array> array, int index);
inline void set(int index, int16_t value);
- static Handle<Object> SetValue(Handle<ExternalShortArray> array,
- uint32_t index,
- Handle<Object> value);
-
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
+ static Handle<Object> SetValue(Handle<ExternalInt16Array> array,
+ uint32_t index,
+ Handle<Object> value);
// Casting.
- static inline ExternalShortArray* cast(Object* obj);
+ static inline ExternalInt16Array* cast(Object* obj);
// Dispatched behavior.
- DECLARE_PRINTER(ExternalShortArray)
- DECLARE_VERIFIER(ExternalShortArray)
+ DECLARE_PRINTER(ExternalInt16Array)
+ DECLARE_VERIFIER(ExternalInt16Array)
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalShortArray);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalInt16Array);
};
-class ExternalUnsignedShortArray: public ExternalArray {
+class ExternalUint16Array: public ExternalArray {
public:
// Setter and getter.
inline uint16_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalUint16Array> array,
+ int index);
inline void set(int index, uint16_t value);
- static Handle<Object> SetValue(Handle<ExternalUnsignedShortArray> array,
- uint32_t index,
- Handle<Object> value);
-
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
+ static Handle<Object> SetValue(Handle<ExternalUint16Array> array,
+ uint32_t index,
+ Handle<Object> value);
// Casting.
- static inline ExternalUnsignedShortArray* cast(Object* obj);
+ static inline ExternalUint16Array* cast(Object* obj);
// Dispatched behavior.
- DECLARE_PRINTER(ExternalUnsignedShortArray)
- DECLARE_VERIFIER(ExternalUnsignedShortArray)
+ DECLARE_PRINTER(ExternalUint16Array)
+ DECLARE_VERIFIER(ExternalUint16Array)
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedShortArray);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUint16Array);
};
-class ExternalIntArray: public ExternalArray {
+class ExternalInt32Array: public ExternalArray {
public:
// Setter and getter.
inline int32_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalInt32Array> array, int index);
inline void set(int index, int32_t value);
- static Handle<Object> SetValue(Handle<ExternalIntArray> array,
- uint32_t index,
- Handle<Object> value);
-
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
+ static Handle<Object> SetValue(Handle<ExternalInt32Array> array,
+ uint32_t index,
+ Handle<Object> value);
// Casting.
- static inline ExternalIntArray* cast(Object* obj);
+ static inline ExternalInt32Array* cast(Object* obj);
// Dispatched behavior.
- DECLARE_PRINTER(ExternalIntArray)
- DECLARE_VERIFIER(ExternalIntArray)
+ DECLARE_PRINTER(ExternalInt32Array)
+ DECLARE_VERIFIER(ExternalInt32Array)
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalIntArray);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalInt32Array);
};
-class ExternalUnsignedIntArray: public ExternalArray {
+class ExternalUint32Array: public ExternalArray {
public:
// Setter and getter.
inline uint32_t get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalUint32Array> array,
+ int index);
inline void set(int index, uint32_t value);
- static Handle<Object> SetValue(Handle<ExternalUnsignedIntArray> array,
- uint32_t index,
- Handle<Object> value);
-
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
+ static Handle<Object> SetValue(Handle<ExternalUint32Array> array,
+ uint32_t index,
+ Handle<Object> value);
// Casting.
- static inline ExternalUnsignedIntArray* cast(Object* obj);
+ static inline ExternalUint32Array* cast(Object* obj);
// Dispatched behavior.
- DECLARE_PRINTER(ExternalUnsignedIntArray)
- DECLARE_VERIFIER(ExternalUnsignedIntArray)
+ DECLARE_PRINTER(ExternalUint32Array)
+ DECLARE_VERIFIER(ExternalUint32Array)
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUnsignedIntArray);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalUint32Array);
};
-class ExternalFloatArray: public ExternalArray {
+class ExternalFloat32Array: public ExternalArray {
public:
// Setter and getter.
inline float get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalFloat32Array> array,
+ int index);
inline void set(int index, float value);
- static Handle<Object> SetValue(Handle<ExternalFloatArray> array,
- uint32_t index,
- Handle<Object> value);
-
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
+ static Handle<Object> SetValue(Handle<ExternalFloat32Array> array,
+ uint32_t index,
+ Handle<Object> value);
// Casting.
- static inline ExternalFloatArray* cast(Object* obj);
+ static inline ExternalFloat32Array* cast(Object* obj);
// Dispatched behavior.
- DECLARE_PRINTER(ExternalFloatArray)
- DECLARE_VERIFIER(ExternalFloatArray)
+ DECLARE_PRINTER(ExternalFloat32Array)
+ DECLARE_VERIFIER(ExternalFloat32Array)
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloatArray);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloat32Array);
};
-class ExternalDoubleArray: public ExternalArray {
+class ExternalFloat64Array: public ExternalArray {
public:
// Setter and getter.
inline double get_scalar(int index);
- MUST_USE_RESULT inline MaybeObject* get(int index);
+ static inline Handle<Object> get(Handle<ExternalFloat64Array> array,
+ int index);
inline void set(int index, double value);
- static Handle<Object> SetValue(Handle<ExternalDoubleArray> array,
- uint32_t index,
- Handle<Object> value);
-
// This accessor applies the correct conversion from Smi, HeapNumber
// and undefined.
- MUST_USE_RESULT MaybeObject* SetValue(uint32_t index, Object* value);
+ static Handle<Object> SetValue(Handle<ExternalFloat64Array> array,
+ uint32_t index,
+ Handle<Object> value);
// Casting.
- static inline ExternalDoubleArray* cast(Object* obj);
+ static inline ExternalFloat64Array* cast(Object* obj);
// Dispatched behavior.
- DECLARE_PRINTER(ExternalDoubleArray)
- DECLARE_VERIFIER(ExternalDoubleArray)
+ DECLARE_PRINTER(ExternalFloat64Array)
+ DECLARE_VERIFIER(ExternalFloat64Array)
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalDoubleArray);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalFloat64Array);
};
+class FixedTypedArrayBase: public FixedArrayBase {
+ public:
+ // Casting:
+ static inline FixedTypedArrayBase* cast(Object* obj);
+
+ static const int kDataOffset = kHeaderSize;
+
+ inline int size();
+
+ inline int TypedArraySize(InstanceType type);
+
+ // Use with care: returns raw pointer into heap.
+ inline void* DataPtr();
+
+ inline int DataSize();
+
+ private:
+ inline int DataSize(InstanceType type);
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArrayBase);
+};
+
+
+template <class Traits>
+class FixedTypedArray: public FixedTypedArrayBase {
+ public:
+ typedef typename Traits::ElementType ElementType;
+ static const InstanceType kInstanceType = Traits::kInstanceType;
+
+ // Casting:
+ static inline FixedTypedArray<Traits>* cast(Object* obj);
+
+ static inline int ElementOffset(int index) {
+ return kDataOffset + index * sizeof(ElementType);
+ }
+
+ static inline int SizeFor(int length) {
+ return ElementOffset(length);
+ }
+
+ inline ElementType get_scalar(int index);
+ static inline Handle<Object> get(Handle<FixedTypedArray> array, int index);
+ inline void set(int index, ElementType value);
+
+ static inline ElementType from_int(int value);
+ static inline ElementType from_double(double value);
+
+ // This accessor applies the correct conversion from Smi, HeapNumber
+ // and undefined.
+ static Handle<Object> SetValue(Handle<FixedTypedArray<Traits> > array,
+ uint32_t index,
+ Handle<Object> value);
+
+ DECLARE_PRINTER(FixedTypedArray)
+ DECLARE_VERIFIER(FixedTypedArray)
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArray);
+};
+
+#define FIXED_TYPED_ARRAY_TRAITS(Type, type, TYPE, elementType, size) \
+ class Type##ArrayTraits { \
+ public: /* NOLINT */ \
+ typedef elementType ElementType; \
+ static const InstanceType kInstanceType = FIXED_##TYPE##_ARRAY_TYPE; \
+ static const char* Designator() { return #type " array"; } \
+ static inline Handle<Object> ToHandle(Isolate* isolate, \
+ elementType scalar); \
+ static inline elementType defaultValue(); \
+ }; \
+ \
+ typedef FixedTypedArray<Type##ArrayTraits> Fixed##Type##Array;
+
+TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)
+
+#undef FIXED_TYPED_ARRAY_TRAITS
+
// DeoptimizationInputData is a fixed array used to hold the deoptimization
// data for code generated by the Hydrogen/Lithium compiler. It also
// contains information about functions that were inlined. If N different
@@ -4834,7 +5301,9 @@ class DeoptimizationInputData: public FixedArray {
static const int kLiteralArrayIndex = 2;
static const int kOsrAstIdIndex = 3;
static const int kOsrPcOffsetIndex = 4;
- static const int kFirstDeoptEntryIndex = 5;
+ static const int kOptimizationIdIndex = 5;
+ static const int kSharedFunctionInfoIndex = 6;
+ static const int kFirstDeoptEntryIndex = 7;
// Offsets of deopt entry elements relative to the start of the entry.
static const int kAstIdRawOffset = 0;
@@ -4857,6 +5326,8 @@ class DeoptimizationInputData: public FixedArray {
DEFINE_ELEMENT_ACCESSORS(LiteralArray, FixedArray)
DEFINE_ELEMENT_ACCESSORS(OsrAstId, Smi)
DEFINE_ELEMENT_ACCESSORS(OsrPcOffset, Smi)
+ DEFINE_ELEMENT_ACCESSORS(OptimizationId, Smi)
+ DEFINE_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
#undef DEFINE_ELEMENT_ACCESSORS
@@ -4889,9 +5360,9 @@ class DeoptimizationInputData: public FixedArray {
}
// Allocates a DeoptimizationInputData.
- MUST_USE_RESULT static MaybeObject* Allocate(Isolate* isolate,
- int deopt_entry_count,
- PretenureFlag pretenure);
+ static Handle<DeoptimizationInputData> New(Isolate* isolate,
+ int deopt_entry_count,
+ PretenureFlag pretenure);
// Casting.
static inline DeoptimizationInputData* cast(Object* obj);
@@ -4936,9 +5407,9 @@ class DeoptimizationOutputData: public FixedArray {
}
// Allocates a DeoptimizationOutputData.
- MUST_USE_RESULT static MaybeObject* Allocate(Isolate* isolate,
- int number_of_deopt_points,
- PretenureFlag pretenure);
+ static Handle<DeoptimizationOutputData> New(Isolate* isolate,
+ int number_of_deopt_points,
+ PretenureFlag pretenure);
// Casting.
static inline DeoptimizationOutputData* cast(Object* obj);
@@ -4952,49 +5423,6 @@ class DeoptimizationOutputData: public FixedArray {
// Forward declaration.
class Cell;
class PropertyCell;
-
-// TypeFeedbackCells is a fixed array used to hold the association between
-// cache cells and AST ids for code generated by the full compiler.
-// The format of the these objects is
-// [i * 2]: Global property cell of ith cache cell.
-// [i * 2 + 1]: Ast ID for ith cache cell.
-class TypeFeedbackCells: public FixedArray {
- public:
- int CellCount() { return length() / 2; }
- static int LengthOfFixedArray(int cell_count) { return cell_count * 2; }
-
- // Accessors for AST ids associated with cache values.
- inline TypeFeedbackId AstId(int index);
- inline void SetAstId(int index, TypeFeedbackId id);
-
- // Accessors for global property cells holding the cache values.
- inline Cell* GetCell(int index);
- inline void SetCell(int index, Cell* cell);
-
- // The object that indicates an uninitialized cache.
- static inline Handle<Object> UninitializedSentinel(Isolate* isolate);
-
- // 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);
-
- // Casting.
- static inline TypeFeedbackCells* cast(Object* obj);
-
- static const int kForInFastCaseMarker = 0;
- static const int kForInSlowCaseMarker = 1;
-};
-
-
-// Forward declaration.
class SafepointEntry;
class TypeFeedbackInfo;
@@ -5017,7 +5445,6 @@ class Code: public HeapObject {
V(LOAD_IC) \
V(KEYED_LOAD_IC) \
V(CALL_IC) \
- V(KEYED_CALL_IC) \
V(STORE_IC) \
V(KEYED_STORE_IC) \
V(BINARY_OP_IC) \
@@ -5077,7 +5504,6 @@ class Code: public HeapObject {
// the kind of the code object.
// FUNCTION => type feedback information.
// STUB => various things, e.g. a SMI
- // OPTIMIZED_FUNCTION => the next_code_link for optimized code list.
DECL_ACCESSORS(raw_type_feedback_info, Object)
inline Object* type_feedback_info();
inline void set_type_feedback_info(
@@ -5115,24 +5541,10 @@ class Code: public HeapObject {
// [flags]: Access to specific code flags.
inline Kind kind();
- inline Kind handler_kind() {
- return static_cast<Kind>(arguments_count());
- }
inline InlineCacheState ic_state(); // Only valid for IC stubs.
inline ExtraICState extra_ic_state(); // Only valid for IC stubs.
- inline ExtraICState extended_extra_ic_state(); // Only valid for
- // non-call IC stubs.
- static bool needs_extended_extra_ic_state(Kind kind) {
- // TODO(danno): This is a bit of a hack right now since there are still
- // clients of this API that pass "extra" values in for argc. These clients
- // should be retrofitted to used ExtendedExtraICState.
- return kind == COMPARE_NIL_IC || kind == TO_BOOLEAN_IC ||
- kind == BINARY_OP_IC;
- }
-
inline StubType type(); // Only valid for monomorphic IC stubs.
- inline int arguments_count(); // Only valid for call IC stubs.
// Testers for IC stub kinds.
inline bool is_inline_cache_stub();
@@ -5143,12 +5555,23 @@ class Code: public HeapObject {
inline bool is_store_stub() { return kind() == STORE_IC; }
inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; }
inline bool is_call_stub() { return kind() == CALL_IC; }
- inline bool is_keyed_call_stub() { return kind() == KEYED_CALL_IC; }
inline bool is_binary_op_stub() { return kind() == BINARY_OP_IC; }
inline bool is_compare_ic_stub() { return kind() == COMPARE_IC; }
inline bool is_compare_nil_ic_stub() { return kind() == COMPARE_NIL_IC; }
inline bool is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; }
inline bool is_keyed_stub();
+ inline bool is_optimized_code() { return kind() == OPTIMIZED_FUNCTION; }
+ inline bool is_weak_stub();
+ inline void mark_as_weak_stub();
+ inline bool is_invalidated_weak_stub();
+ inline void mark_as_invalidated_weak_stub();
+
+ inline bool CanBeWeakStub() {
+ Kind k = kind();
+ return (k == LOAD_IC || k == STORE_IC || k == KEYED_LOAD_IC ||
+ k == KEYED_STORE_IC || k == COMPARE_NIL_IC) &&
+ ic_state() == MONOMORPHIC;
+ }
inline void set_raw_kind_specific_flags1(int value);
inline void set_raw_kind_specific_flags2(int value);
@@ -5212,11 +5635,6 @@ class Code: public HeapObject {
inline bool back_edges_patched_for_osr();
inline void set_back_edges_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();
- inline void set_check_type(CheckType value);
-
// [to_boolean_foo]: For kind TO_BOOLEAN_IC tells what state the stub is in.
inline byte to_boolean_state();
@@ -5231,18 +5649,22 @@ class Code: public HeapObject {
inline bool marked_for_deoptimization();
inline void set_marked_for_deoptimization(bool flag);
+ // [constant_pool]: The constant pool for this function.
+ inline ConstantPoolArray* constant_pool();
+ inline void set_constant_pool(Object* constant_pool);
+
// Get the safepoint entry for the given pc.
SafepointEntry GetSafepointEntry(Address pc);
// Find an object in a stub with a specified map
Object* FindNthObject(int n, Map* match_map);
- void ReplaceNthObject(int n, Map* match_map, Object* replace_with);
+
+ // Find the first allocation site in an IC stub.
+ AllocationSite* FindFirstAllocationSite();
// Find the first map in an IC stub.
Map* FindFirstMap();
void FindAllMaps(MapHandleList* maps);
- void FindAllTypes(TypeHandleList* types);
- void ReplaceFirstMap(Map* replace);
// Find the first handler in an IC stub.
Code* FindFirstHandler();
@@ -5254,7 +5676,12 @@ class Code: public HeapObject {
// Find the first name in an IC stub.
Name* FindFirstName();
- void ReplaceNthCell(int n, Cell* replace_with);
+ class FindAndReplacePattern;
+ // For each (map-to-find, object-to-replace) pair in the pattern, this
+ // function replaces the corresponding placeholder in the code with the
+ // object-to-replace. The function assumes that pairs in the pattern come in
+ // the same order as the placeholders in the code.
+ void FindAndReplace(const FindAndReplacePattern& pattern);
// The entire code object including its header is copied verbatim to the
// snapshot so that it can be written in one, fast, memcpy during
@@ -5271,23 +5698,24 @@ class Code: public HeapObject {
InlineCacheState ic_state = UNINITIALIZED,
ExtraICState extra_ic_state = kNoExtraICState,
StubType type = NORMAL,
- int argc = -1,
InlineCacheHolderFlag holder = OWN_MAP);
static inline Flags ComputeMonomorphicFlags(
Kind kind,
ExtraICState extra_ic_state = kNoExtraICState,
InlineCacheHolderFlag holder = OWN_MAP,
+ StubType type = NORMAL);
+
+ static inline Flags ComputeHandlerFlags(
+ Kind handler_kind,
StubType type = NORMAL,
- int argc = -1);
+ InlineCacheHolderFlag holder = OWN_MAP);
static inline InlineCacheState ExtractICStateFromFlags(Flags flags);
static inline StubType ExtractTypeFromFlags(Flags flags);
static inline Kind ExtractKindFromFlags(Flags flags);
static inline InlineCacheHolderFlag ExtractCacheHolderFromFlags(Flags flags);
static inline ExtraICState ExtractExtraICStateFromFlags(Flags flags);
- static inline ExtraICState ExtractExtendedExtraICStateFromFlags(Flags flags);
- static inline int ExtractArgumentsCountFromFlags(Flags flags);
static inline Flags RemoveTypeFromFlags(Flags flags);
@@ -5357,9 +5785,8 @@ class Code: public HeapObject {
void ClearInlineCaches();
void ClearInlineCaches(Kind kind);
- void ClearTypeFeedbackCells(Heap* heap);
-
BailoutId TranslatePcOffsetToAstId(uint32_t pc_offset);
+ uint32_t TranslateAstIdToPcOffset(BailoutId ast_id);
#define DECLARE_CODE_AGE_ENUM(X) k##X##CodeAge,
enum Age {
@@ -5383,7 +5810,7 @@ class Code: public HeapObject {
static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
void MakeOlder(MarkingParity);
- static bool IsYoungSequence(byte* sequence);
+ static bool IsYoungSequence(Isolate* isolate, byte* sequence);
bool IsOld();
Age GetAge();
// Gets the raw code age, including psuedo code-age values such as
@@ -5400,7 +5827,17 @@ class Code: public HeapObject {
void VerifyEmbeddedObjectsDependency();
#endif
- static bool IsWeakEmbeddedObject(Kind kind, Object* object);
+ inline bool CanContainWeakObjects() {
+ return is_optimized_code() || is_weak_stub();
+ }
+
+ inline bool IsWeakObject(Object* object) {
+ return (is_optimized_code() && IsWeakObjectInOptimizedCode(object)) ||
+ (is_weak_stub() && IsWeakObjectInIC(object));
+ }
+
+ static inline bool IsWeakObjectInOptimizedCode(Object* object);
+ static inline bool IsWeakObjectInIC(Object* object);
// Max loop nesting marker used to postpose OSR. We don't take loop
// nesting that is deeper than 5 levels into account.
@@ -5414,8 +5851,8 @@ class Code: public HeapObject {
kHandlerTableOffset + kPointerSize;
static const int kTypeFeedbackInfoOffset =
kDeoptimizationDataOffset + kPointerSize;
- static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset; // Shared.
- static const int kGCMetadataOffset = kTypeFeedbackInfoOffset + kPointerSize;
+ static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset + kPointerSize;
+ static const int kGCMetadataOffset = kNextCodeLinkOffset + kPointerSize;
static const int kICAgeOffset =
kGCMetadataOffset + kPointerSize;
static const int kFlagsOffset = kICAgeOffset + kIntSize;
@@ -5424,8 +5861,9 @@ class Code: public HeapObject {
kKindSpecificFlags1Offset + kIntSize;
// Note: We might be able to squeeze this into the flags above.
static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
+ static const int kConstantPoolOffset = kPrologueOffset + kPointerSize;
- static const int kHeaderPaddingStart = kPrologueOffset + kIntSize;
+ static const int kHeaderPaddingStart = kConstantPoolOffset + kIntSize;
// Add padding to align the instruction start following right after
// the Code object header.
@@ -5434,7 +5872,6 @@ class Code: public HeapObject {
// Byte offsets within kKindSpecificFlags1Offset.
static const int kOptimizableOffset = kKindSpecificFlags1Offset;
- static const int kCheckTypeOffset = kKindSpecificFlags1Offset;
static const int kFullCodeFlags = kOptimizableOffset + 1;
class FullCodeFlagsHasDeoptimizationSupportField:
@@ -5451,10 +5888,8 @@ class Code: public HeapObject {
class CacheHolderField: public BitField<InlineCacheHolderFlag, 5, 1> {};
class KindField: public BitField<Kind, 6, 4> {};
// TODO(bmeurer): Bit 10 is available for free use. :-)
- class ExtraICStateField: public BitField<ExtraICState, 11, 6> {};
- class ExtendedExtraICStateField: public BitField<ExtraICState, 11,
+ class ExtraICStateField: public BitField<ExtraICState, 11,
PlatformSmiTagging::kSmiValueSize - 11 + 1> {}; // NOLINT
- STATIC_ASSERT(ExtraICStateField::kShift == ExtendedExtraICStateField::kShift);
// KindSpecificFlags1 layout (STUB and OPTIMIZED_FUNCTION)
static const int kStackSlotsFirstBit = 0;
@@ -5465,11 +5900,17 @@ class Code: public HeapObject {
static const int kMarkedForDeoptimizationFirstBit =
kStackSlotsFirstBit + kStackSlotsBitCount + 1;
static const int kMarkedForDeoptimizationBitCount = 1;
+ static const int kWeakStubFirstBit =
+ kMarkedForDeoptimizationFirstBit + kMarkedForDeoptimizationBitCount;
+ static const int kWeakStubBitCount = 1;
+ static const int kInvalidatedWeakStubFirstBit =
+ kWeakStubFirstBit + kWeakStubBitCount;
+ static const int kInvalidatedWeakStubBitCount = 1;
STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
STATIC_ASSERT(kHasFunctionCacheFirstBit + kHasFunctionCacheBitCount <= 32);
- STATIC_ASSERT(kMarkedForDeoptimizationFirstBit +
- kMarkedForDeoptimizationBitCount <= 32);
+ STATIC_ASSERT(kInvalidatedWeakStubFirstBit +
+ kInvalidatedWeakStubBitCount <= 32);
class StackSlotsField: public BitField<int,
kStackSlotsFirstBit, kStackSlotsBitCount> {}; // NOLINT
@@ -5478,6 +5919,12 @@ class Code: public HeapObject {
class MarkedForDeoptimizationField: public BitField<bool,
kMarkedForDeoptimizationFirstBit,
kMarkedForDeoptimizationBitCount> {}; // NOLINT
+ class WeakStubField: public BitField<bool,
+ kWeakStubFirstBit,
+ kWeakStubBitCount> {}; // NOLINT
+ class InvalidatedWeakStubField: public BitField<bool,
+ kInvalidatedWeakStubFirstBit,
+ kInvalidatedWeakStubBitCount> {}; // NOLINT
// KindSpecificFlags2 layout (ALL)
static const int kIsCrankshaftedBit = 0;
@@ -5508,26 +5955,16 @@ class Code: public HeapObject {
class BackEdgesPatchedForOSRField: public BitField<bool,
kIsCrankshaftedBit + 1 + 29, 1> {}; // NOLINT
- // Signed field cannot be encoded using the BitField class.
- static const int kArgumentsCountShift = 17;
- static const int kArgumentsCountMask = ~((1 << kArgumentsCountShift) - 1);
- static const int kArgumentsBits =
- PlatformSmiTagging::kSmiValueSize - Code::kArgumentsCountShift + 1;
+ static const int kArgumentsBits = 16;
static const int kMaxArguments = (1 << kArgumentsBits) - 1;
- // ICs can use either argument count or ExtendedExtraIC, since their storage
- // overlaps.
- STATIC_ASSERT(ExtraICStateField::kShift +
- ExtraICStateField::kSize + kArgumentsBits ==
- ExtendedExtraICStateField::kShift +
- ExtendedExtraICStateField::kSize);
-
// This constant should be encodable in an ARM instruction.
static const int kFlagsNotUsedInLookup =
TypeField::kMask | CacheHolderField::kMask;
private:
friend class RelocIterator;
+ friend class Deoptimizer; // For FindCodeAgeSequence.
void ClearInlineCaches(Kind* kind);
@@ -5535,7 +5972,7 @@ class Code: public HeapObject {
byte* FindCodeAgeSequence();
static void GetCodeAgeAndParity(Code* code, Age* age,
MarkingParity* parity);
- static void GetCodeAgeAndParity(byte* sequence, Age* age,
+ static void GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
MarkingParity* parity);
static Code* GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity);
@@ -5572,9 +6009,14 @@ class CompilationInfo;
class DependentCode: public FixedArray {
public:
enum DependencyGroup {
+ // Group of IC stubs that weakly embed this map and depend on being
+ // invalidated when the map is garbage collected. Dependent IC stubs form
+ // a linked list. This group stores only the head of the list. This means
+ // that the number_of_entries(kWeakICGroup) is 0 or 1.
+ kWeakICGroup,
// Group of code that weakly embed this map and depend on being
// deoptimized when the map is garbage collected.
- kWeaklyEmbeddedGroup,
+ kWeakCodeGroup,
// Group of code that embed a transition to this map, and depend on being
// deoptimized when the transition is replaced by a new version.
kTransitionGroup,
@@ -5589,6 +6031,12 @@ class DependentCode: public FixedArray {
// Group of code that depends on global property values in property cells
// not being changed.
kPropertyCellChangedGroup,
+ // Group of code that omit run-time type checks for the field(s) introduced
+ // by this map.
+ kFieldTypeGroup,
+ // Group of code that omit run-time type checks for initial maps of
+ // constructors.
+ kInitialMapChangedGroup,
// Group of code that depends on tenuring information in AllocationSites
// not being changed.
kAllocationSiteTenuringChangedGroup,
@@ -5623,6 +6071,10 @@ class DependentCode: public FixedArray {
void DeoptimizeDependentCodeGroup(Isolate* isolate,
DependentCode::DependencyGroup group);
+ bool MarkCodeForDeoptimization(Isolate* isolate,
+ DependentCode::DependencyGroup group);
+ void AddToDependentICList(Handle<Code> stub);
+
// The following low-level accessors should only be used by this class
// and the mark compact collector.
inline int number_of_entries(DependencyGroup group);
@@ -5695,14 +6147,17 @@ class Map: public HeapObject {
kDescriptorIndexBitCount, kDescriptorIndexBitCount> {}; // NOLINT
STATIC_ASSERT(kDescriptorIndexBitCount + kDescriptorIndexBitCount == 20);
class IsShared: public BitField<bool, 20, 1> {};
- class FunctionWithPrototype: public BitField<bool, 21, 1> {};
- class DictionaryMap: public BitField<bool, 22, 1> {};
- class OwnsDescriptors: public BitField<bool, 23, 1> {};
- class HasInstanceCallHandler: public BitField<bool, 24, 1> {};
- class Deprecated: public BitField<bool, 25, 1> {};
- class IsFrozen: public BitField<bool, 26, 1> {};
- class IsUnstable: public BitField<bool, 27, 1> {};
- class IsMigrationTarget: public BitField<bool, 28, 1> {};
+ class DictionaryMap: public BitField<bool, 21, 1> {};
+ class OwnsDescriptors: public BitField<bool, 22, 1> {};
+ class HasInstanceCallHandler: public BitField<bool, 23, 1> {};
+ class Deprecated: public BitField<bool, 24, 1> {};
+ class IsFrozen: public BitField<bool, 25, 1> {};
+ class IsUnstable: public BitField<bool, 26, 1> {};
+ class IsMigrationTarget: public BitField<bool, 27, 1> {};
+ class DoneInobjectSlackTracking: public BitField<bool, 28, 1> {};
+ // Keep this bit field at the very end for better code in
+ // Builtins::kJSConstructStubGeneric stub.
+ class ConstructionCount: public BitField<int, 29, 3> {};
// Tells whether the object in the prototype property will be used
// for instances created from this function. If the prototype
@@ -5774,15 +6229,13 @@ class Map: public HeapObject {
inline void set_elements_kind(ElementsKind elements_kind) {
ASSERT(elements_kind < kElementsKindCount);
- ASSERT(kElementsKindCount <= (1 << kElementsKindBitCount));
- set_bit_field2((bit_field2() & ~kElementsKindMask) |
- (elements_kind << kElementsKindShift));
+ ASSERT(kElementsKindCount <= (1 << Map::ElementsKindBits::kSize));
+ set_bit_field2(Map::ElementsKindBits::update(bit_field2(), elements_kind));
ASSERT(this->elements_kind() == elements_kind);
}
inline ElementsKind elements_kind() {
- return static_cast<ElementsKind>(
- (bit_field2() & kElementsKindMask) >> kElementsKindShift);
+ return Map::ElementsKindBits::decode(bit_field2());
}
// Tells whether the instance has fast elements that are only Smis.
@@ -5807,21 +6260,25 @@ class Map: public HeapObject {
return IsFastElementsKind(elements_kind());
}
- inline bool has_non_strict_arguments_elements() {
- return elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS;
+ inline bool has_sloppy_arguments_elements() {
+ return elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS;
}
inline bool has_external_array_elements() {
return IsExternalArrayElementsKind(elements_kind());
}
+ inline bool has_fixed_typed_array_elements() {
+ return IsFixedTypedArrayElementsKind(elements_kind());
+ }
+
inline bool has_dictionary_elements() {
return IsDictionaryElementsKind(elements_kind());
}
inline bool has_slow_elements_kind() {
return elements_kind() == DICTIONARY_ELEMENTS
- || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS;
+ || elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS;
}
static bool IsValidElementsTransition(ElementsKind from_kind,
@@ -5834,29 +6291,18 @@ class Map: public HeapObject {
inline bool HasTransitionArray();
inline bool HasElementsTransition();
inline Map* elements_transition_map();
- MUST_USE_RESULT inline MaybeObject* set_elements_transition_map(
- Map* transitioned_map);
- inline void SetTransition(int transition_index, Map* target);
+ static Handle<TransitionArray> SetElementsTransitionMap(
+ Handle<Map> map, Handle<Map> transitioned_map);
inline Map* GetTransition(int transition_index);
+ inline int SearchTransition(Name* name);
+ inline FixedArrayBase* GetInitialElements();
- static Handle<TransitionArray> AddTransition(Handle<Map> map,
- Handle<Name> key,
- Handle<Map> target,
- SimpleTransitionFlag flag);
-
- MUST_USE_RESULT inline MaybeObject* AddTransition(Name* key,
- Map* target,
- SimpleTransitionFlag flag);
DECL_ACCESSORS(transitions, TransitionArray)
- inline void ClearTransitions(Heap* heap,
- WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
-
- void DeprecateTransitionTree();
- void DeprecateTarget(Name* key, DescriptorArray* new_descriptors);
Map* FindRootMap();
- Map* FindUpdatedMap(int verbatim, int length, DescriptorArray* descriptors);
- Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
+ Map* FindFieldOwner(int descriptor);
+
+ inline int GetInObjectPropertyOffset(int index);
int NumberOfFields();
@@ -5864,13 +6310,19 @@ class Map: public HeapObject {
int target_number_of_fields,
int target_inobject,
int target_unused);
- static Handle<Map> GeneralizeAllFieldRepresentations(
- Handle<Map> map,
- Representation new_representation);
+ static Handle<Map> GeneralizeAllFieldRepresentations(Handle<Map> map);
+ static Handle<HeapType> GeneralizeFieldType(Handle<HeapType> type1,
+ Handle<HeapType> type2,
+ Isolate* isolate)
+ V8_WARN_UNUSED_RESULT;
+ static void GeneralizeFieldType(Handle<Map> map,
+ int modify_index,
+ Handle<HeapType> new_field_type);
static Handle<Map> GeneralizeRepresentation(
Handle<Map> map,
int modify_index,
Representation new_representation,
+ Handle<HeapType> new_field_type,
StoreMode store_mode);
static Handle<Map> CopyGeneralizeAllRepresentations(
Handle<Map> map,
@@ -5878,26 +6330,18 @@ class Map: public HeapObject {
StoreMode store_mode,
PropertyAttributes attributes,
const char* reason);
+ static Handle<Map> CopyGeneralizeAllRepresentations(
+ Handle<Map> map,
+ int modify_index,
+ StoreMode store_mode,
+ const char* reason);
- void PrintGeneralization(FILE* file,
- const char* reason,
- int modify_index,
- int split,
- int descriptors,
- bool constant_to_field,
- Representation old_representation,
- Representation new_representation);
+ static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode);
// Returns the constructor name (the name (possibly, inferred name) of the
// function that was used to instantiate the object).
String* constructor_name();
- // Tells whether the map is attached to SharedFunctionInfo
- // (for inobject slack tracking).
- inline void set_attached_to_shared_function_info(bool value);
-
- inline bool attached_to_shared_function_info();
-
// Tells whether the map is shared between objects that may have different
// behavior. If true, the map should never be modified, instead a clone
// should be created and modified.
@@ -5932,7 +6376,7 @@ 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.
+ // [dependent code]: list of optimized codes that weakly embed this map.
DECL_ACCESSORS(dependent_code, DependentCode)
// [back pointer]: points back to the parent map from which a transition
@@ -5953,13 +6397,8 @@ class Map: public HeapObject {
// 2 + 2 * i: prototype
// 3 + 2 * i: target map
inline FixedArray* GetPrototypeTransitions();
- MUST_USE_RESULT inline MaybeObject* SetPrototypeTransitions(
- FixedArray* prototype_transitions);
inline bool HasPrototypeTransitions();
- inline HeapObject* UncheckedPrototypeTransitions();
- inline TransitionArray* unchecked_transition_array();
-
static const int kProtoTransitionHeaderSize = 1;
static const int kProtoTransitionNumberOfEntriesOffset = 0;
static const int kProtoTransitionElementsPerEntry = 2;
@@ -6037,6 +6476,10 @@ class Map: public HeapObject {
inline bool is_stable();
inline void set_migration_target(bool value);
inline bool is_migration_target();
+ inline void set_done_inobject_slack_tracking(bool value);
+ inline bool done_inobject_slack_tracking();
+ inline void set_construction_count(int value);
+ inline int construction_count();
inline void deprecate();
inline bool is_deprecated();
inline bool CanBeDeprecated();
@@ -6045,57 +6488,54 @@ class Map: public HeapObject {
// is found by re-transitioning from the root of the transition tree using the
// descriptor array of the map. Returns NULL if no updated map is found.
// This method also applies any pending migrations along the prototype chain.
- static Handle<Map> CurrentMapForDeprecated(Handle<Map> map);
+ static MaybeHandle<Map> CurrentMapForDeprecated(Handle<Map> map)
+ V8_WARN_UNUSED_RESULT;
// Same as above, but does not touch the prototype chain.
- static Handle<Map> CurrentMapForDeprecatedInternal(Handle<Map> map);
+ static MaybeHandle<Map> CurrentMapForDeprecatedInternal(Handle<Map> map)
+ V8_WARN_UNUSED_RESULT;
- static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
- MUST_USE_RESULT MaybeObject* RawCopy(int instance_size);
- MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors();
static Handle<Map> CopyDropDescriptors(Handle<Map> map);
- MUST_USE_RESULT MaybeObject* CopyDropDescriptors();
- static Handle<Map> CopyReplaceDescriptors(Handle<Map> map,
- Handle<DescriptorArray> descriptors,
- TransitionFlag flag,
- Handle<Name> name);
- MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors(
- DescriptorArray* descriptors,
- TransitionFlag flag,
- Name* name = NULL,
- SimpleTransitionFlag simple_flag = FULL_TRANSITION);
- static Handle<Map> CopyInstallDescriptors(
+ static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
+ Descriptor* descriptor,
+ TransitionFlag flag);
+
+ MUST_USE_RESULT static MaybeHandle<Map> CopyWithField(
Handle<Map> map,
- int new_descriptor,
- Handle<DescriptorArray> descriptors);
- MUST_USE_RESULT MaybeObject* ShareDescriptor(DescriptorArray* descriptors,
- Descriptor* descriptor);
- MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor,
- TransitionFlag flag);
- MUST_USE_RESULT MaybeObject* CopyInsertDescriptor(Descriptor* descriptor,
- TransitionFlag flag);
- MUST_USE_RESULT MaybeObject* CopyReplaceDescriptor(
- DescriptorArray* descriptors,
- Descriptor* descriptor,
- int index,
+ Handle<Name> name,
+ Handle<HeapType> type,
+ PropertyAttributes attributes,
+ Representation representation,
+ TransitionFlag flag);
+
+ MUST_USE_RESULT static MaybeHandle<Map> CopyWithConstant(
+ Handle<Map> map,
+ Handle<Name> name,
+ Handle<Object> constant,
+ PropertyAttributes attributes,
TransitionFlag flag);
- MUST_USE_RESULT MaybeObject* AsElementsKind(ElementsKind kind);
- MUST_USE_RESULT MaybeObject* CopyAsElementsKind(ElementsKind kind,
- TransitionFlag flag);
+ // Returns a new map with all transitions dropped from the given map and
+ // the ElementsKind set.
+ static Handle<Map> TransitionElementsTo(Handle<Map> map,
+ ElementsKind to_kind);
+
+ static Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind kind);
+
+ static Handle<Map> CopyAsElementsKind(Handle<Map> map,
+ ElementsKind kind,
+ TransitionFlag flag);
static Handle<Map> CopyForObserved(Handle<Map> map);
- static Handle<Map> CopyNormalized(Handle<Map> map,
- PropertyNormalizationMode mode,
- NormalizedMapSharingMode sharing);
+ static Handle<Map> CopyForFreeze(Handle<Map> map);
- inline void AppendDescriptor(Descriptor* desc,
- const DescriptorArray::WhitenessWitness&);
+ inline void AppendDescriptor(Descriptor* desc);
// Returns a copy of the map, with all transitions dropped from the
// instance descriptors.
static Handle<Map> Copy(Handle<Map> map);
- MUST_USE_RESULT MaybeObject* Copy();
+ static Handle<Map> Create(Handle<JSFunction> constructor,
+ int extra_inobject_properties);
// Returns the next free property index (only valid for FAST MODE).
int NextFreePropertyIndex();
@@ -6115,9 +6555,6 @@ class Map: public HeapObject {
// Casting.
static inline Map* cast(Object* obj);
- // Locate an accessor in the instance descriptor.
- AccessorDescriptor* FindAccessor(Name* name);
-
// Code cache operations.
// Clears the code cache.
@@ -6127,7 +6564,6 @@ class Map: public HeapObject {
static void UpdateCodeCache(Handle<Map> map,
Handle<Name> name,
Handle<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.
@@ -6154,14 +6590,6 @@ class Map: public HeapObject {
// Computes a hash value for this map, to be used in HashTables and such.
int Hash();
- bool EquivalentToForTransition(Map* other);
-
- // Compares this map to another to see if they describe equivalent objects.
- // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
- // it had exactly zero inobject properties.
- // The "shared" flags of both this map and |other| are ignored.
- bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
-
// Returns the map that this map transitions to if its elements_kind
// is changed to |elements_kind|, or NULL if no such map is cached yet.
// |safe_to_add_transitions| is set to false if adding transitions is not
@@ -6174,15 +6602,6 @@ class Map: public HeapObject {
Handle<Map> FindTransitionedMap(MapHandleList* candidates);
Map* FindTransitionedMap(MapList* candidates);
- // Zaps the contents of backing data structures. Note that the
- // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects
- // holding weak references when incremental marking is used, because it also
- // iterates over objects that are otherwise unreachable.
- // In general we only want to call these functions in release mode when
- // heap verification is turned on.
- void ZapPrototypeTransitions();
- void ZapTransitions();
-
bool CanTransition() {
// Only JSObject and subtypes have map transitions and back pointers.
STATIC_ASSERT(LAST_TYPE == LAST_JS_OBJECT_TYPE);
@@ -6192,6 +6611,10 @@ class Map: public HeapObject {
bool IsJSObjectMap() {
return instance_type() >= FIRST_JS_OBJECT_TYPE;
}
+ bool IsJSProxyMap() {
+ InstanceType type = instance_type();
+ return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
+ }
bool IsJSGlobalProxyMap() {
return instance_type() == JS_GLOBAL_PROXY_TYPE;
}
@@ -6203,18 +6626,17 @@ class Map: public HeapObject {
return type == JS_GLOBAL_OBJECT_TYPE || type == JS_BUILTINS_OBJECT_TYPE;
}
- // 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 CanOmitMapChecks();
- void AddDependentCompilationInfo(DependentCode::DependencyGroup group,
- CompilationInfo* info);
+ static void AddDependentCompilationInfo(Handle<Map> map,
+ DependentCode::DependencyGroup group,
+ CompilationInfo* info);
- void AddDependentCode(DependentCode::DependencyGroup group,
- Handle<Code> code);
+ static void AddDependentCode(Handle<Map> map,
+ DependentCode::DependencyGroup group,
+ Handle<Code> code);
+ static void AddDependentIC(Handle<Map> map,
+ Handle<Code> stub);
bool IsMapInArrayPrototypeChain();
@@ -6242,18 +6664,16 @@ class Map: public HeapObject {
// transitions are in the form of a map where the keys are prototype objects
// and the values are the maps the are transitioned to.
static const int kMaxCachedPrototypeTransitions = 256;
- static Handle<Map> GetPrototypeTransition(Handle<Map> map,
- Handle<Object> prototype);
- static Handle<Map> PutPrototypeTransition(Handle<Map> map,
- Handle<Object> prototype,
- Handle<Map> target_map);
+ static Handle<Map> TransitionToPrototype(Handle<Map> map,
+ Handle<Object> prototype);
static const int kMaxPreAllocatedPropertyFields = 255;
// Layout description.
static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
- static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize;
+ static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize;
+ static const int kPrototypeOffset = kBitField3Offset + kPointerSize;
static const int kConstructorOffset = kPrototypeOffset + kPointerSize;
// Storage for the transition array is overloaded to directly contain a back
// pointer if unused. When the map has transitions, the back pointer is
@@ -6265,13 +6685,12 @@ class Map: public HeapObject {
kTransitionsOrBackPointerOffset + 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;
+ static const int kSize = kDependentCodeOffset + kPointerSize;
// Layout of pointer fields. Heap iteration code relies on them
// being continuously allocated.
static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
- static const int kPointerFieldsEndOffset = kBitField3Offset + kPointerSize;
+ static const int kPointerFieldsEndOffset = kSize;
// Byte offsets within kInstanceSizesOffset.
static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
@@ -6285,52 +6704,134 @@ class Map: public HeapObject {
static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte;
// Byte offsets within kInstanceAttributesOffset attributes.
+#if V8_TARGET_LITTLE_ENDIAN
+ // Order instance type and bit field together such that they can be loaded
+ // together as a 16-bit word with instance type in the lower 8 bits regardless
+ // of endianess.
static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0;
- static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 1;
- static const int kBitFieldOffset = kInstanceAttributesOffset + 2;
- static const int kBitField2Offset = kInstanceAttributesOffset + 3;
+ static const int kBitFieldOffset = kInstanceAttributesOffset + 1;
+#else
+ static const int kBitFieldOffset = kInstanceAttributesOffset + 0;
+ static const int kInstanceTypeOffset = kInstanceAttributesOffset + 1;
+#endif
+ static const int kBitField2Offset = kInstanceAttributesOffset + 2;
+ static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 3;
- STATIC_CHECK(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset);
+ STATIC_ASSERT(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset);
// Bit positions for bit field.
- static const int kUnused = 0; // To be used for marking recently used maps.
- static const int kHasNonInstancePrototype = 1;
- static const int kIsHiddenPrototype = 2;
- static const int kHasNamedInterceptor = 3;
- static const int kHasIndexedInterceptor = 4;
- static const int kIsUndetectable = 5;
- static const int kIsObserved = 6;
- static const int kIsAccessCheckNeeded = 7;
+ static const int kHasNonInstancePrototype = 0;
+ static const int kIsHiddenPrototype = 1;
+ static const int kHasNamedInterceptor = 2;
+ static const int kHasIndexedInterceptor = 3;
+ static const int kIsUndetectable = 4;
+ static const int kIsObserved = 5;
+ static const int kIsAccessCheckNeeded = 6;
+ class FunctionWithPrototype: public BitField<bool, 7, 1> {};
// Bit positions for bit field 2
static const int kIsExtensible = 0;
static const int kStringWrapperSafeForDefaultValueOf = 1;
- static const int kAttachedToSharedFunctionInfo = 2;
- // No bits can be used after kElementsKindFirstBit, they are all reserved for
- // storing ElementKind.
- static const int kElementsKindShift = 3;
- static const int kElementsKindBitCount = 5;
+ // Currently bit 2 is not used.
+ class ElementsKindBits: public BitField<ElementsKind, 3, 5> {};
// Derived values from bit field 2
- static const int kElementsKindMask = (-1 << kElementsKindShift) &
- ((1 << (kElementsKindShift + kElementsKindBitCount)) - 1);
static const int8_t kMaximumBitField2FastElementValue = static_cast<int8_t>(
- (FAST_ELEMENTS + 1) << Map::kElementsKindShift) - 1;
+ (FAST_ELEMENTS + 1) << Map::ElementsKindBits::kShift) - 1;
static const int8_t kMaximumBitField2FastSmiElementValue =
static_cast<int8_t>((FAST_SMI_ELEMENTS + 1) <<
- Map::kElementsKindShift) - 1;
+ Map::ElementsKindBits::kShift) - 1;
static const int8_t kMaximumBitField2FastHoleyElementValue =
static_cast<int8_t>((FAST_HOLEY_ELEMENTS + 1) <<
- Map::kElementsKindShift) - 1;
+ Map::ElementsKindBits::kShift) - 1;
static const int8_t kMaximumBitField2FastHoleySmiElementValue =
static_cast<int8_t>((FAST_HOLEY_SMI_ELEMENTS + 1) <<
- Map::kElementsKindShift) - 1;
+ Map::ElementsKindBits::kShift) - 1;
typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
kPointerFieldsEndOffset,
kSize> BodyDescriptor;
+ // Compares this map to another to see if they describe equivalent objects.
+ // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
+ // it had exactly zero inobject properties.
+ // The "shared" flags of both this map and |other| are ignored.
+ bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
+
private:
+ bool EquivalentToForTransition(Map* other);
+ static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
+ static Handle<Map> ShareDescriptor(Handle<Map> map,
+ Handle<DescriptorArray> descriptors,
+ Descriptor* descriptor);
+ static Handle<Map> CopyInstallDescriptors(
+ Handle<Map> map,
+ int new_descriptor,
+ Handle<DescriptorArray> descriptors);
+ static Handle<Map> CopyAddDescriptor(Handle<Map> map,
+ Descriptor* descriptor,
+ TransitionFlag flag);
+ static Handle<Map> CopyReplaceDescriptors(
+ Handle<Map> map,
+ Handle<DescriptorArray> descriptors,
+ TransitionFlag flag,
+ MaybeHandle<Name> maybe_name,
+ SimpleTransitionFlag simple_flag = FULL_TRANSITION);
+ static Handle<Map> CopyReplaceDescriptor(Handle<Map> map,
+ Handle<DescriptorArray> descriptors,
+ Descriptor* descriptor,
+ int index,
+ TransitionFlag flag);
+
+ static Handle<Map> CopyNormalized(Handle<Map> map,
+ PropertyNormalizationMode mode,
+ NormalizedMapSharingMode sharing);
+
+ // 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();
+
+ static Handle<Map> TransitionElementsToSlow(Handle<Map> object,
+ ElementsKind to_kind);
+
+ // Zaps the contents of backing data structures. Note that the
+ // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects
+ // holding weak references when incremental marking is used, because it also
+ // iterates over objects that are otherwise unreachable.
+ // In general we only want to call these functions in release mode when
+ // heap verification is turned on.
+ void ZapPrototypeTransitions();
+ void ZapTransitions();
+
+ void DeprecateTransitionTree();
+ void DeprecateTarget(Name* key, DescriptorArray* new_descriptors);
+
+ Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
+
+ void UpdateDescriptor(int descriptor_number, Descriptor* desc);
+
+ void PrintGeneralization(FILE* file,
+ const char* reason,
+ int modify_index,
+ int split,
+ int descriptors,
+ bool constant_to_field,
+ Representation old_representation,
+ Representation new_representation,
+ HeapType* old_field_type,
+ HeapType* new_field_type);
+
+ static inline void SetPrototypeTransitions(
+ Handle<Map> map,
+ Handle<FixedArray> prototype_transitions);
+
+ static Handle<Map> GetPrototypeTransition(Handle<Map> map,
+ Handle<Object> prototype);
+ static Handle<Map> PutPrototypeTransition(Handle<Map> map,
+ Handle<Object> prototype,
+ Handle<Map> target_map);
+
DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
};
@@ -6403,9 +6904,6 @@ class Script: public Struct {
// extracted.
DECL_ACCESSORS(column_offset, Smi)
- // [data]: additional data associated with this script.
- DECL_ACCESSORS(data, Object)
-
// [context_data]: context data for the context this script was compiled in.
DECL_ACCESSORS(context_data, Object)
@@ -6451,6 +6949,22 @@ class Script: public Struct {
// resource is accessible. Otherwise, always return true.
inline bool HasValidSource();
+ // Convert code position into column number.
+ static int GetColumnNumber(Handle<Script> script, int code_pos);
+
+ // Convert code position into (zero-based) line number.
+ // The non-handlified version does not allocate, but may be much slower.
+ static int GetLineNumber(Handle<Script> script, int code_pos);
+ int GetLineNumber(int code_pos);
+
+ static Handle<Object> GetNameOrSourceURL(Handle<Script> script);
+
+ // Init line_ends array with code positions of line ends inside script source.
+ static void InitLineEnds(Handle<Script> script);
+
+ // Get the JS object wrapping the given script; create it if none exists.
+ static Handle<JSObject> GetWrapper(Handle<Script> script);
+
// Dispatched behavior.
DECLARE_PRINTER(Script)
DECLARE_VERIFIER(Script)
@@ -6459,8 +6973,7 @@ class Script: public Struct {
static const int kNameOffset = kSourceOffset + kPointerSize;
static const int kLineOffsetOffset = kNameOffset + kPointerSize;
static const int kColumnOffsetOffset = kLineOffsetOffset + kPointerSize;
- static const int kDataOffset = kColumnOffsetOffset + kPointerSize;
- static const int kContextOffset = kDataOffset + kPointerSize;
+ static const int kContextOffset = kColumnOffsetOffset + kPointerSize;
static const int kWrapperOffset = kContextOffset + kPointerSize;
static const int kTypeOffset = kWrapperOffset + kPointerSize;
static const int kLineEndsOffset = kTypeOffset + kPointerSize;
@@ -6473,6 +6986,8 @@ class Script: public Struct {
static const int kSize = kFlagsOffset + kPointerSize;
private:
+ int GetLineNumberWithArray(int code_pos);
+
// Bit positions in the flags field.
static const int kCompilationTypeBit = 0;
static const int kCompilationStateBit = 1;
@@ -6491,29 +7006,26 @@ class Script: public Struct {
//
// Installation of ids for the selected builtin functions is handled
// by the bootstrapper.
-#define FUNCTIONS_WITH_ID_LIST(V) \
- V(Array.prototype, push, ArrayPush) \
- V(Array.prototype, pop, ArrayPop) \
- V(Function.prototype, apply, FunctionApply) \
- V(String.prototype, charCodeAt, StringCharCodeAt) \
- V(String.prototype, charAt, StringCharAt) \
- V(String, fromCharCode, StringFromCharCode) \
- V(Math, floor, MathFloor) \
- V(Math, round, MathRound) \
- V(Math, ceil, MathCeil) \
- V(Math, abs, MathAbs) \
- V(Math, log, MathLog) \
- V(Math, sin, MathSin) \
- V(Math, cos, MathCos) \
- V(Math, tan, MathTan) \
- V(Math, asin, MathASin) \
- V(Math, acos, MathACos) \
- V(Math, atan, MathATan) \
- V(Math, exp, MathExp) \
- V(Math, sqrt, MathSqrt) \
- V(Math, pow, MathPow) \
- V(Math, max, MathMax) \
- V(Math, min, MathMin) \
+#define FUNCTIONS_WITH_ID_LIST(V) \
+ V(Array.prototype, indexOf, ArrayIndexOf) \
+ V(Array.prototype, lastIndexOf, ArrayLastIndexOf) \
+ V(Array.prototype, push, ArrayPush) \
+ V(Array.prototype, pop, ArrayPop) \
+ V(Array.prototype, shift, ArrayShift) \
+ V(Function.prototype, apply, FunctionApply) \
+ V(String.prototype, charCodeAt, StringCharCodeAt) \
+ V(String.prototype, charAt, StringCharAt) \
+ V(String, fromCharCode, StringFromCharCode) \
+ V(Math, floor, MathFloor) \
+ V(Math, round, MathRound) \
+ V(Math, ceil, MathCeil) \
+ V(Math, abs, MathAbs) \
+ V(Math, log, MathLog) \
+ V(Math, exp, MathExp) \
+ V(Math, sqrt, MathSqrt) \
+ V(Math, pow, MathPow) \
+ V(Math, max, MathMax) \
+ V(Math, min, MathMin) \
V(Math, imul, MathImul)
enum BuiltinFunctionId {
@@ -6524,7 +7036,9 @@ enum BuiltinFunctionId {
#undef DECLARE_FUNCTION_ID
// Fake id for a special case of Math.pow. Note, it continues the
// list of math functions.
- kMathPowHalf
+ kMathPowHalf,
+ // Installed only on --harmony-maths.
+ kMathClz32
};
@@ -6543,14 +7057,16 @@ class SharedFunctionInfo: public HeapObject {
// and a shared literals array or Smi(0) if none.
DECL_ACCESSORS(optimized_code_map, Object)
- // Returns index i of the entry with the specified context. At position
- // i - 1 is the context, position i the code, and i + 1 the literals array.
- // Returns -1 when no matching entry is found.
- int SearchOptimizedCodeMap(Context* native_context);
+ // Returns index i of the entry with the specified context and OSR entry.
+ // At position i - 1 is the context, position i the code, and i + 1 the
+ // literals array. Returns -1 when no matching entry is found.
+ int SearchOptimizedCodeMap(Context* native_context, BailoutId osr_ast_id);
// Installs optimized code from the code map on the given closure. The
// index has to be consistent with a search result as defined above.
- void InstallFromOptimizedCodeMap(JSFunction* function, int index);
+ FixedArray* GetLiteralsFromOptimizedCodeMap(int index);
+
+ Code* GetCodeFromOptimizedCodeMap(int index);
// Clear optimized code map.
void ClearOptimizedCodeMap();
@@ -6558,25 +7074,26 @@ class SharedFunctionInfo: public HeapObject {
// Removed a specific optimized code object from the optimized code map.
void EvictFromOptimizedCodeMap(Code* optimized_code, const char* reason);
+ void ClearTypeFeedbackInfo();
+
// Trims the optimized code map after entries have been removed.
void TrimOptimizedCodeMap(int shrink_by);
// Add a new entry to the optimized code map.
- MUST_USE_RESULT MaybeObject* AddToOptimizedCodeMap(Context* native_context,
- Code* code,
- FixedArray* literals);
static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
Handle<Context> native_context,
Handle<Code> code,
- Handle<FixedArray> literals);
+ Handle<FixedArray> literals,
+ BailoutId osr_ast_id);
// Layout description of the optimized code map.
static const int kNextMapIndex = 0;
static const int kEntriesStart = 1;
- static const int kEntryLength = 3;
- static const int kFirstContextSlot = FixedArray::kHeaderSize + kPointerSize;
- static const int kFirstCodeSlot = FixedArray::kHeaderSize + 2 * kPointerSize;
- static const int kSecondEntryIndex = kEntryLength + kEntriesStart;
+ static const int kContextOffset = 0;
+ static const int kCachedCodeOffset = 1;
+ static const int kLiteralsOffset = 2;
+ static const int kOsrAstIdOffset = 3;
+ static const int kEntryLength = 4;
static const int kInitialLength = kEntriesStart + kEntryLength;
// [scope_info]: Scope info.
@@ -6605,101 +7122,11 @@ class SharedFunctionInfo: public HeapObject {
inline int expected_nof_properties();
inline void set_expected_nof_properties(int value);
- // Inobject slack tracking is the way to reclaim unused inobject space.
- //
- // The instance size is initially determined by adding some slack to
- // expected_nof_properties (to allow for a few extra properties added
- // after the constructor). There is no guarantee that the extra space
- // will not be wasted.
- //
- // Here is the algorithm to reclaim the unused inobject space:
- // - Detect the first constructor call for this SharedFunctionInfo.
- // When it happens enter the "in progress" state: remember the
- // constructor's initial_map and install a special construct stub that
- // counts constructor calls.
- // - While the tracking is in progress create objects filled with
- // one_pointer_filler_map instead of undefined_value. This way they can be
- // resized quickly and safely.
- // - Once enough (kGenerousAllocationCount) objects have been created
- // compute the 'slack' (traverse the map transition tree starting from the
- // initial_map and find the lowest value of unused_property_fields).
- // - Traverse the transition tree again and decrease the instance size
- // of every map. Existing objects will resize automatically (they are
- // filled with one_pointer_filler_map). All further allocations will
- // use the adjusted instance size.
- // - Decrease expected_nof_properties so that an allocations made from
- // another context will use the adjusted instance size too.
- // - Exit "in progress" state by clearing the reference to the initial_map
- // and setting the regular construct stub (generic or inline).
- //
- // The above is the main event sequence. Some special cases are possible
- // while the tracking is in progress:
- //
- // - GC occurs.
- // Check if the initial_map is referenced by any live objects (except this
- // SharedFunctionInfo). If it is, continue tracking as usual.
- // If it is not, clear the reference and reset the tracking state. The
- // tracking will be initiated again on the next constructor call.
- //
- // - The constructor is called from another context.
- // Immediately complete the tracking, perform all the necessary changes
- // to maps. This is necessary because there is no efficient way to track
- // multiple initial_maps.
- // Proceed to create an object in the current context (with the adjusted
- // size).
- //
- // - A different constructor function sharing the same SharedFunctionInfo is
- // called in the same context. This could be another closure in the same
- // context, or the first function could have been disposed.
- // This is handled the same way as the previous case.
- //
- // Important: inobject slack tracking is not attempted during the snapshot
- // creation.
-
- static const int kGenerousAllocationCount = 8;
-
- // [construction_count]: Counter for constructor calls made during
- // the tracking phase.
- inline int construction_count();
- inline void set_construction_count(int value);
-
- // [initial_map]: initial map of the first function called as a constructor.
- // Saved for the duration of the tracking phase.
- // This is a weak link (GC resets it to undefined_value if no other live
- // object reference this map).
- DECL_ACCESSORS(initial_map, Object)
-
- // True if the initial_map is not undefined and the countdown stub is
- // installed.
- inline bool IsInobjectSlackTrackingInProgress();
-
- // Starts the tracking.
- // Stores the initial map and installs the countdown stub.
- // IsInobjectSlackTrackingInProgress is normally true after this call,
- // except when tracking have not been started (e.g. the map has no unused
- // properties or the snapshot is being built).
- void StartInobjectSlackTracking(Map* map);
-
- // Completes the tracking.
- // IsInobjectSlackTrackingInProgress is false after this call.
- void CompleteInobjectSlackTracking();
-
- // Invoked before pointers in SharedFunctionInfo are being marked.
- // Also clears the optimized code map.
- inline void BeforeVisitingPointers();
-
- // Clears the initial_map before the GC marking phase to ensure the reference
- // is weak. IsInobjectSlackTrackingInProgress is false after this call.
- void DetachInitialMap();
-
- // Restores the link to the initial map after the GC marking phase.
- // IsInobjectSlackTrackingInProgress is true after this call.
- void AttachInitialMap(Map* map);
-
- // False if there are definitely no live objects created from this function.
- // True if live objects _may_ exist (existence not guaranteed).
- // May go back from true to false after GC.
- DECL_BOOLEAN_ACCESSORS(live_objects_may_exist)
+ // [feedback_vector] - accumulates ast node feedback from full-codegen and
+ // (increasingly) from crankshafted code where sufficient feedback isn't
+ // available. Currently the field is duplicated in
+ // TypeFeedbackInfo::feedback_vector, but the allocation is done here.
+ DECL_ACCESSORS(feedback_vector, FixedArray)
// [instance class name]: class name for instances.
DECL_ACCESSORS(instance_class_name, Object)
@@ -6772,6 +7199,7 @@ class SharedFunctionInfo: public HeapObject {
inline void set_ast_node_count(int count);
inline int profiler_ticks();
+ inline void set_profiler_ticks(int ticks);
// Inline cache age is used to infer whether the function survived a context
// disposal or not. In the former case we reset the opt_count.
@@ -6795,20 +7223,9 @@ class SharedFunctionInfo: public HeapObject {
// spending time attempting to optimize it again.
DECL_BOOLEAN_ACCESSORS(optimization_disabled)
- // Indicates the language mode of the function's code as defined by the
- // current harmony drafts for the next ES language standard. Possible
- // values are:
- // 1. CLASSIC_MODE - Unrestricted syntax and semantics, same as in ES5.
- // 2. STRICT_MODE - Restricted syntax and semantics, same as in ES5.
- // 3. EXTENDED_MODE - Only available under the harmony flag, not part of ES5.
- inline LanguageMode language_mode();
- inline void set_language_mode(LanguageMode language_mode);
-
- // Indicates whether the language mode of this function is CLASSIC_MODE.
- inline bool is_classic_mode();
-
- // Indicates whether the language mode of this function is EXTENDED_MODE.
- inline bool is_extended_mode();
+ // Indicates the language mode.
+ inline StrictMode strict_mode();
+ inline void set_strict_mode(StrictMode strict_mode);
// False if the function definitely does not allocate an arguments object.
DECL_BOOLEAN_ACCESSORS(uses_arguments)
@@ -6934,12 +7351,6 @@ class SharedFunctionInfo: public HeapObject {
void ResetForNewContext(int new_ic_age);
- // Helper to compile the shared code. Returns true on success, false on
- // failure (e.g., stack overflow during compilation). This is only used by
- // the debugger, it is not possible to compile without a context otherwise.
- static bool CompileLazy(Handle<SharedFunctionInfo> shared,
- ClearExceptionFlag flag);
-
// Casting.
static inline SharedFunctionInfo* cast(Object* obj);
@@ -6960,16 +7371,12 @@ class SharedFunctionInfo: public HeapObject {
static const int kScriptOffset = kFunctionDataOffset + kPointerSize;
static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize;
- static const int kInitialMapOffset =
+ static const int kFeedbackVectorOffset =
kInferredNameOffset + kPointerSize;
- // ast_node_count is a Smi field. It could be grouped with another Smi field
- // into a PSEUDO_SMI_ACCESSORS pair (on x64), if one becomes available.
- static const int kAstNodeCountOffset =
- kInitialMapOffset + kPointerSize;
#if V8_HOST_ARCH_32_BIT
// Smi fields.
static const int kLengthOffset =
- kAstNodeCountOffset + kPointerSize;
+ kFeedbackVectorOffset + kPointerSize;
static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
static const int kExpectedNofPropertiesOffset =
kFormalParameterCountOffset + kPointerSize;
@@ -6987,9 +7394,13 @@ class SharedFunctionInfo: public HeapObject {
kCompilerHintsOffset + kPointerSize;
static const int kCountersOffset =
kOptCountAndBailoutReasonOffset + kPointerSize;
+ static const int kAstNodeCountOffset =
+ kCountersOffset + kPointerSize;
+ static const int kProfilerTicksOffset =
+ kAstNodeCountOffset + kPointerSize;
// Total size.
- static const int kSize = kCountersOffset + kPointerSize;
+ static const int kSize = kProfilerTicksOffset + kPointerSize;
#else
// The only reason to use smi fields instead of int fields
// is to allow iteration without maps decoding during
@@ -7001,7 +7412,7 @@ class SharedFunctionInfo: public HeapObject {
// word is not set and thus this word cannot be treated as pointer
// to HeapObject during old space traversal.
static const int kLengthOffset =
- kAstNodeCountOffset + kPointerSize;
+ kFeedbackVectorOffset + kPointerSize;
static const int kFormalParameterCountOffset =
kLengthOffset + kIntSize;
@@ -7022,30 +7433,23 @@ class SharedFunctionInfo: public HeapObject {
static const int kOptCountAndBailoutReasonOffset =
kCompilerHintsOffset + kIntSize;
-
static const int kCountersOffset =
kOptCountAndBailoutReasonOffset + kIntSize;
- // Total size.
- static const int kSize = kCountersOffset + kIntSize;
+ static const int kAstNodeCountOffset =
+ kCountersOffset + kIntSize;
+ static const int kProfilerTicksOffset =
+ kAstNodeCountOffset + kIntSize;
-#endif
+ // Total size.
+ static const int kSize = kProfilerTicksOffset + kIntSize;
- // The construction counter for inobject slack tracking is stored in the
- // most significant byte of compiler_hints which is otherwise unused.
- // Its offset depends on the endian-ness of the architecture.
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- static const int kConstructionCountOffset = kCompilerHintsOffset + 3;
-#elif __BYTE_ORDER == __BIG_ENDIAN
- static const int kConstructionCountOffset = kCompilerHintsOffset + 0;
-#else
-#error Unknown byte ordering
#endif
static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
typedef FixedBodyDescriptor<kNameOffset,
- kInitialMapOffset + kPointerSize,
+ kFeedbackVectorOffset + kPointerSize,
kSize> BodyDescriptor;
// Bit positions in start_position_and_type.
@@ -7060,10 +7464,8 @@ class SharedFunctionInfo: public HeapObject {
enum CompilerHints {
kAllowLazyCompilation,
kAllowLazyCompilationWithoutContext,
- kLiveObjectsMayExist,
kOptimizationDisabled,
kStrictModeFunction,
- kExtendedModeFunction,
kUsesArguments,
kHasDuplicateParameters,
kNative,
@@ -7108,26 +7510,18 @@ class SharedFunctionInfo: public HeapObject {
static const int kStrictModeBitWithinByte =
(kStrictModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
- static const int kExtendedModeBitWithinByte =
- (kExtendedModeFunction + kCompilerHintsSmiTagSize) % kBitsPerByte;
-
static const int kNativeBitWithinByte =
(kNative + kCompilerHintsSmiTagSize) % kBitsPerByte;
-#if __BYTE_ORDER == __LITTLE_ENDIAN
+#if defined(V8_TARGET_LITTLE_ENDIAN)
static const int kStrictModeByteOffset = kCompilerHintsOffset +
(kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
- static const int kExtendedModeByteOffset = kCompilerHintsOffset +
- (kExtendedModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte;
static const int kNativeByteOffset = kCompilerHintsOffset +
(kNative + kCompilerHintsSmiTagSize) / kBitsPerByte;
-#elif __BYTE_ORDER == __BIG_ENDIAN
+#elif defined(V8_TARGET_BIG_ENDIAN)
static const int kStrictModeByteOffset = kCompilerHintsOffset +
(kCompilerHintsSize - 1) -
((kStrictModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
- static const int kExtendedModeByteOffset = kCompilerHintsOffset +
- (kCompilerHintsSize - 1) -
- ((kExtendedModeFunction + kCompilerHintsSmiTagSize) / kBitsPerByte);
static const int kNativeByteOffset = kCompilerHintsOffset +
(kCompilerHintsSize - 1) -
((kNative + kCompilerHintsSmiTagSize) / kBitsPerByte);
@@ -7158,6 +7552,9 @@ class JSGeneratorObject: public JSObject {
// cannot be resumed.
inline int continuation();
inline void set_continuation(int continuation);
+ inline bool is_closed();
+ inline bool is_executing();
+ inline bool is_suspended();
// [operand_stack]: Saved operand stack.
DECL_ACCESSORS(operand_stack, FixedArray)
@@ -7192,7 +7589,7 @@ class JSGeneratorObject: public JSObject {
enum ResumeMode { NEXT, THROW };
// Yielding from a generator returns an object with the following inobject
- // properties. See Context::generator_result_map() for the map.
+ // properties. See Context::iterator_result_map() for the map.
static const int kResultValuePropertyIndex = 0;
static const int kResultDonePropertyIndex = 1;
static const int kResultPropertyCount = 2;
@@ -7259,6 +7656,9 @@ class JSFunction: public JSObject {
// Tells whether this function is builtin.
inline bool IsBuiltin();
+ // Tells whether this function is defined in a native script.
+ inline bool IsNative();
+
// Tells whether or not the function needs arguments adaption.
inline bool NeedsArgumentsAdaption();
@@ -7270,29 +7670,65 @@ class JSFunction: public JSObject {
// Mark this function for lazy recompilation. The function will be
// recompiled the next time it is executed.
- void MarkForLazyRecompilation();
- void MarkForConcurrentRecompilation();
- void MarkInRecompileQueue();
-
- // Helpers to compile this function. Returns true on success, false on
- // failure (e.g., stack overflow during compilation).
- static bool EnsureCompiled(Handle<JSFunction> function,
- ClearExceptionFlag flag);
- static bool CompileLazy(Handle<JSFunction> function,
- ClearExceptionFlag flag);
- static Handle<Code> CompileOsr(Handle<JSFunction> function,
- BailoutId osr_ast_id,
- ClearExceptionFlag flag);
- static bool CompileOptimized(Handle<JSFunction> function,
- ClearExceptionFlag flag);
+ void MarkForOptimization();
+ void MarkForConcurrentOptimization();
+ void MarkInOptimizationQueue();
// Tells whether or not the function is already marked for lazy
// recompilation.
- inline bool IsMarkedForLazyRecompilation();
- inline bool IsMarkedForConcurrentRecompilation();
+ inline bool IsMarkedForOptimization();
+ inline bool IsMarkedForConcurrentOptimization();
// Tells whether or not the function is on the concurrent recompilation queue.
- inline bool IsInRecompileQueue();
+ inline bool IsInOptimizationQueue();
+
+ // Inobject slack tracking is the way to reclaim unused inobject space.
+ //
+ // The instance size is initially determined by adding some slack to
+ // expected_nof_properties (to allow for a few extra properties added
+ // after the constructor). There is no guarantee that the extra space
+ // will not be wasted.
+ //
+ // Here is the algorithm to reclaim the unused inobject space:
+ // - Detect the first constructor call for this JSFunction.
+ // When it happens enter the "in progress" state: initialize construction
+ // counter in the initial_map and set the |done_inobject_slack_tracking|
+ // flag.
+ // - While the tracking is in progress create objects filled with
+ // one_pointer_filler_map instead of undefined_value. This way they can be
+ // resized quickly and safely.
+ // - Once enough (kGenerousAllocationCount) objects have been created
+ // compute the 'slack' (traverse the map transition tree starting from the
+ // initial_map and find the lowest value of unused_property_fields).
+ // - Traverse the transition tree again and decrease the instance size
+ // of every map. Existing objects will resize automatically (they are
+ // filled with one_pointer_filler_map). All further allocations will
+ // use the adjusted instance size.
+ // - SharedFunctionInfo's expected_nof_properties left unmodified since
+ // allocations made using different closures could actually create different
+ // kind of objects (see prototype inheritance pattern).
+ //
+ // Important: inobject slack tracking is not attempted during the snapshot
+ // creation.
+
+ static const int kGenerousAllocationCount = Map::ConstructionCount::kMax;
+ static const int kFinishSlackTracking = 1;
+ static const int kNoSlackTracking = 0;
+
+ // True if the initial_map is set and the object constructions countdown
+ // counter is not zero.
+ inline bool IsInobjectSlackTrackingInProgress();
+
+ // Starts the tracking.
+ // Initializes object constructions countdown counter in the initial map.
+ // IsInobjectSlackTrackingInProgress is normally true after this call,
+ // except when tracking have not been started (e.g. the map has no unused
+ // properties or the snapshot is being built).
+ void StartInobjectSlackTracking();
+
+ // Completes the tracking.
+ // IsInobjectSlackTrackingInProgress is false after this call.
+ void CompleteInobjectSlackTracking();
// [literals_or_bindings]: Fixed array holding either
// the materialized literals or the bindings of a bound function.
@@ -7337,7 +7773,7 @@ class JSFunction: public JSObject {
// After prototype is removed, it will not be created when accessed, and
// [[Construct]] from this function will not be allowed.
- void RemovePrototype();
+ bool RemovePrototype();
inline bool should_have_prototype();
// Accessor for this function's initial map's [[class]]
@@ -7424,6 +7860,9 @@ class JSGlobalProxy : public JSObject {
// It is null value if this object is not used by any context.
DECL_ACCESSORS(native_context, Object)
+ // [hash]: The hash code property (undefined if not initialized yet).
+ DECL_ACCESSORS(hash, Object)
+
// Casting.
static inline JSGlobalProxy* cast(Object* obj);
@@ -7435,7 +7874,8 @@ class JSGlobalProxy : public JSObject {
// Layout description.
static const int kNativeContextOffset = JSObject::kHeaderSize;
- static const int kSize = kNativeContextOffset + kPointerSize;
+ static const int kHashOffset = kNativeContextOffset + kPointerSize;
+ static const int kSize = kHashOffset + kPointerSize;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSGlobalProxy);
@@ -7464,15 +7904,6 @@ class GlobalObject: public JSObject {
// Retrieve the property cell used to store a property.
PropertyCell* GetPropertyCell(LookupResult* result);
- // This is like GetProperty, but is used when you know the lookup won't fail
- // 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(Name* key) {
- Object* answer = GetProperty(key)->ToObjectUnchecked();
- return answer;
- }
-
// Casting.
static inline GlobalObject* cast(Object* obj);
@@ -7599,7 +8030,7 @@ class JSDate: public JSObject {
// [sec]: caches seconds. Either undefined, smi, or NaN.
DECL_ACCESSORS(sec, Object)
// [cache stamp]: sample of the date cache stamp at the
- // moment when local fields were cached.
+ // moment when chached fields were cached.
DECL_ACCESSORS(cache_stamp, Object)
// Casting.
@@ -7663,7 +8094,7 @@ class JSDate: public JSObject {
Object* GetUTCField(FieldIndex index, double value, DateCache* date_cache);
// Computes and caches the cacheable fields of the date.
- inline void SetLocalFields(int64_t local_time_ms, DateCache* date_cache);
+ inline void SetCachedFields(int64_t local_time_ms, DateCache* date_cache);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSDate);
@@ -7687,9 +8118,6 @@ class JSMessageObject: public JSObject {
// [script]: the script from which the error message originated.
DECL_ACCESSORS(script, Object)
- // [stack_trace]: the stack trace for this error message.
- DECL_ACCESSORS(stack_trace, Object)
-
// [stack_frames]: an array of stack frames for this error object.
DECL_ACCESSORS(stack_frames, Object)
@@ -7712,8 +8140,7 @@ class JSMessageObject: public JSObject {
static const int kTypeOffset = JSObject::kHeaderSize;
static const int kArgumentsOffset = kTypeOffset + kPointerSize;
static const int kScriptOffset = kArgumentsOffset + kPointerSize;
- static const int kStackTraceOffset = kScriptOffset + kPointerSize;
- static const int kStackFramesOffset = kStackTraceOffset + kPointerSize;
+ static const int kStackFramesOffset = kScriptOffset + kPointerSize;
static const int kStartPositionOffset = kStackFramesOffset + kPointerSize;
static const int kEndPositionOffset = kStartPositionOffset + kPointerSize;
static const int kSize = kEndPositionOffset + kPointerSize;
@@ -7877,38 +8304,32 @@ class CompilationCacheShape : public BaseShape<HashTableKey*> {
return key->HashForObject(object);
}
- MUST_USE_RESULT static MaybeObject* AsObject(Heap* heap,
- HashTableKey* key) {
- return key->AsObject(heap);
- }
+ static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
static const int kPrefixSize = 0;
static const int kEntrySize = 2;
};
-class CompilationCacheTable: public HashTable<CompilationCacheShape,
+class CompilationCacheTable: public HashTable<CompilationCacheTable,
+ CompilationCacheShape,
HashTableKey*> {
public:
// Find cached value for a string key, otherwise return null.
- Object* Lookup(String* src, Context* context);
- Object* LookupEval(String* src,
- Context* context,
- LanguageMode language_mode,
- int scope_position);
- Object* LookupRegExp(String* source, JSRegExp::Flags flags);
- MUST_USE_RESULT MaybeObject* Put(String* src,
- Context* context,
- Object* value);
- MUST_USE_RESULT MaybeObject* PutEval(String* src,
- Context* context,
- SharedFunctionInfo* value,
- int scope_position);
- MUST_USE_RESULT MaybeObject* PutRegExp(String* src,
- JSRegExp::Flags flags,
- FixedArray* value);
-
- // Remove given value from cache.
+ Handle<Object> Lookup(Handle<String> src, Handle<Context> context);
+ Handle<Object> LookupEval(Handle<String> src, Handle<Context> context,
+ StrictMode strict_mode, int scope_position);
+ Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags);
+ static Handle<CompilationCacheTable> Put(
+ Handle<CompilationCacheTable> cache, Handle<String> src,
+ Handle<Context> context, Handle<Object> value);
+ static Handle<CompilationCacheTable> PutEval(
+ Handle<CompilationCacheTable> cache, Handle<String> src,
+ Handle<Context> context, Handle<SharedFunctionInfo> value,
+ int scope_position);
+ static Handle<CompilationCacheTable> PutRegExp(
+ Handle<CompilationCacheTable> cache, Handle<String> src,
+ JSRegExp::Flags flags, Handle<FixedArray> value);
void Remove(Object* value);
static inline CompilationCacheTable* cast(Object* obj);
@@ -7924,7 +8345,8 @@ class CodeCache: public Struct {
DECL_ACCESSORS(normal_type_cache, Object)
// Add the code object to the cache.
- MUST_USE_RESULT MaybeObject* Update(Name* name, Code* code);
+ static void Update(
+ Handle<CodeCache> cache, Handle<Name> name, Handle<Code> code);
// Lookup code object in the cache. Returns code object if found and undefined
// if not.
@@ -7951,8 +8373,10 @@ class CodeCache: public Struct {
static const int kSize = kNormalTypeCacheOffset + kPointerSize;
private:
- MUST_USE_RESULT MaybeObject* UpdateDefaultCache(Name* name, Code* code);
- MUST_USE_RESULT MaybeObject* UpdateNormalTypeCache(Name* name, Code* code);
+ static void UpdateDefaultCache(
+ Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code);
+ static void UpdateNormalTypeCache(
+ Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code);
Object* LookupDefaultCache(Name* name, Code::Flags flags);
Object* LookupNormalTypeCache(Name* name, Code::Flags flags);
@@ -7980,21 +8404,22 @@ class CodeCacheHashTableShape : public BaseShape<HashTableKey*> {
return key->HashForObject(object);
}
- MUST_USE_RESULT static MaybeObject* AsObject(Heap* heap,
- HashTableKey* key) {
- return key->AsObject(heap);
- }
+ static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
static const int kPrefixSize = 0;
static const int kEntrySize = 2;
};
-class CodeCacheHashTable: public HashTable<CodeCacheHashTableShape,
+class CodeCacheHashTable: public HashTable<CodeCacheHashTable,
+ CodeCacheHashTableShape,
HashTableKey*> {
public:
Object* Lookup(Name* name, Code::Flags flags);
- MUST_USE_RESULT MaybeObject* Put(Name* name, Code* code);
+ static Handle<CodeCacheHashTable> Put(
+ Handle<CodeCacheHashTable> table,
+ Handle<Name> name,
+ Handle<Code> code);
int GetIndex(Name* name, Code::Flags flags);
void RemoveByIndex(int index);
@@ -8018,9 +8443,6 @@ class PolymorphicCodeCache: public Struct {
Code::Flags flags,
Handle<Code> code);
- MUST_USE_RESULT MaybeObject* Update(MapHandleList* maps,
- Code::Flags flags,
- Code* code);
// Returns an undefined value if the entry is not found.
Handle<Object> Lookup(MapHandleList* maps, Code::Flags flags);
@@ -8040,13 +8462,17 @@ class PolymorphicCodeCache: public Struct {
class PolymorphicCodeCacheHashTable
- : public HashTable<CodeCacheHashTableShape, HashTableKey*> {
+ : public HashTable<PolymorphicCodeCacheHashTable,
+ CodeCacheHashTableShape,
+ HashTableKey*> {
public:
Object* Lookup(MapHandleList* maps, int code_kind);
- MUST_USE_RESULT MaybeObject* Put(MapHandleList* maps,
- int code_kind,
- Code* code);
+ static Handle<PolymorphicCodeCacheHashTable> Put(
+ Handle<PolymorphicCodeCacheHashTable> hash_table,
+ MapHandleList* maps,
+ int code_kind,
+ Handle<Code> code);
static inline PolymorphicCodeCacheHashTable* cast(Object* obj);
@@ -8072,7 +8498,6 @@ class TypeFeedbackInfo: public Struct {
inline void set_inlined_type_change_checksum(int checksum);
inline bool matches_inlined_type_change_checksum(int checksum);
- DECL_ACCESSORS(type_feedback_cells, TypeFeedbackCells)
static inline TypeFeedbackInfo* cast(Object* obj);
@@ -8082,8 +8507,23 @@ class TypeFeedbackInfo: public Struct {
static const int kStorage1Offset = HeapObject::kHeaderSize;
static const int kStorage2Offset = kStorage1Offset + kPointerSize;
- static const int kTypeFeedbackCellsOffset = kStorage2Offset + kPointerSize;
- static const int kSize = kTypeFeedbackCellsOffset + kPointerSize;
+ static const int kSize = kStorage2Offset + kPointerSize;
+
+ // TODO(mvstanton): move these sentinel declarations to shared function info.
+ // The object that indicates an uninitialized cache.
+ static inline Handle<Object> UninitializedSentinel(Isolate* isolate);
+
+ // 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);
private:
static const int kTypeChangeChecksumBits = 7;
@@ -8117,23 +8557,24 @@ class AllocationSite: public Struct {
static const int kPretenureMinimumCreated = 100;
// Values for pretenure decision field.
- enum {
+ enum PretenureDecision {
kUndecided = 0,
kDontTenure = 1,
- kTenure = 2,
- kZombie = 3
+ kMaybeTenure = 2,
+ kTenure = 3,
+ kZombie = 4,
+ kLastPretenureDecisionValue = kZombie
};
+ const char* PretenureDecisionName(PretenureDecision decision);
+
DECL_ACCESSORS(transition_info, Object)
// nested_site threads a list of sites that represent nested literals
// walked in a particular order. So [[1, 2], 1, 2] will have one
// nested_site, but [[1, 2], 3, [4]] will have a list of two.
DECL_ACCESSORS(nested_site, Object)
- DECL_ACCESSORS(memento_found_count, Smi)
- DECL_ACCESSORS(memento_create_count, Smi)
- // TODO(mvstanton): we don't need a whole integer to record pretenure
- // decision. Consider sharing space with memento_found_count.
- DECL_ACCESSORS(pretenure_decision, Smi)
+ DECL_ACCESSORS(pretenure_data, Smi)
+ DECL_ACCESSORS(pretenure_create_count, Smi)
DECL_ACCESSORS(dependent_code, DependentCode)
DECL_ACCESSORS(weak_next, Object)
@@ -8142,18 +8583,64 @@ class AllocationSite: public Struct {
// This method is expensive, it should only be called for reporting.
bool IsNestedSite();
+ // transition_info bitfields, for constructed array transition info.
class ElementsKindBits: public BitField<ElementsKind, 0, 15> {};
class UnusedBits: public BitField<int, 15, 14> {};
class DoNotInlineBit: public BitField<bool, 29, 1> {};
- inline void IncrementMementoFoundCount();
+ // Bitfields for pretenure_data
+ class MementoFoundCountBits: public BitField<int, 0, 26> {};
+ class PretenureDecisionBits: public BitField<PretenureDecision, 26, 3> {};
+ class DeoptDependentCodeBit: public BitField<bool, 29, 1> {};
+ STATIC_ASSERT(PretenureDecisionBits::kMax >= kLastPretenureDecisionValue);
+
+ // Increments the mementos found counter and returns true when the first
+ // memento was found for a given allocation site.
+ inline bool IncrementMementoFoundCount();
inline void IncrementMementoCreateCount();
- PretenureFlag GetPretenureMode() {
- int mode = pretenure_decision()->value();
- // Zombie objects "decide" to be untenured.
- return (mode == kTenure) ? TENURED : NOT_TENURED;
+ PretenureFlag GetPretenureMode();
+
+ void ResetPretenureDecision();
+
+ PretenureDecision pretenure_decision() {
+ int value = pretenure_data()->value();
+ return PretenureDecisionBits::decode(value);
+ }
+
+ void set_pretenure_decision(PretenureDecision decision) {
+ int value = pretenure_data()->value();
+ set_pretenure_data(
+ Smi::FromInt(PretenureDecisionBits::update(value, decision)),
+ SKIP_WRITE_BARRIER);
+ }
+
+ bool deopt_dependent_code() {
+ int value = pretenure_data()->value();
+ return DeoptDependentCodeBit::decode(value);
+ }
+
+ void set_deopt_dependent_code(bool deopt) {
+ int value = pretenure_data()->value();
+ set_pretenure_data(
+ Smi::FromInt(DeoptDependentCodeBit::update(value, deopt)),
+ SKIP_WRITE_BARRIER);
+ }
+
+ int memento_found_count() {
+ int value = pretenure_data()->value();
+ return MementoFoundCountBits::decode(value);
+ }
+
+ inline void set_memento_found_count(int count);
+
+ int memento_create_count() {
+ return pretenure_create_count()->value();
+ }
+
+ void set_memento_create_count(int count) {
+ set_pretenure_create_count(Smi::FromInt(count), SKIP_WRITE_BARRIER);
}
// The pretenuring decision is made during gc, and the zombie state allows
@@ -8161,12 +8648,20 @@ class AllocationSite: public Struct {
// a later traversal of new space may discover AllocationMementos that point
// to this AllocationSite.
bool IsZombie() {
- return pretenure_decision()->value() == kZombie;
+ return pretenure_decision() == kZombie;
+ }
+
+ bool IsMaybeTenure() {
+ return pretenure_decision() == kMaybeTenure;
}
inline void MarkZombie();
- inline bool DigestPretenuringFeedback();
+ inline bool MakePretenureDecision(PretenureDecision current_decision,
+ double ratio,
+ bool maximum_size_scavenge);
+
+ inline bool DigestPretenuringFeedback(bool maximum_size_scavenge);
ElementsKind GetElementsKind() {
ASSERT(!SitePointsToLiteral());
@@ -8198,15 +8693,17 @@ class AllocationSite: public Struct {
return transition_info()->IsJSArray() || transition_info()->IsJSObject();
}
- MaybeObject* DigestTransitionFeedback(ElementsKind to_kind);
+ static void DigestTransitionFeedback(Handle<AllocationSite> site,
+ ElementsKind to_kind);
enum Reason {
TENURING,
TRANSITIONS
};
- void AddDependentCompilationInfo(Reason reason, CompilationInfo* info);
- void AddDependentCode(Reason reason, Handle<Code> code);
+ static void AddDependentCompilationInfo(Handle<AllocationSite> site,
+ Reason reason,
+ CompilationInfo* info);
DECLARE_PRINTER(AllocationSite)
DECLARE_VERIFIER(AllocationSite)
@@ -8219,13 +8716,11 @@ class AllocationSite: public Struct {
static const int kTransitionInfoOffset = HeapObject::kHeaderSize;
static const int kNestedSiteOffset = kTransitionInfoOffset + kPointerSize;
- static const int kMementoFoundCountOffset = kNestedSiteOffset + kPointerSize;
- static const int kMementoCreateCountOffset =
- kMementoFoundCountOffset + kPointerSize;
- static const int kPretenureDecisionOffset =
- kMementoCreateCountOffset + kPointerSize;
+ static const int kPretenureDataOffset = kNestedSiteOffset + kPointerSize;
+ static const int kPretenureCreateCountOffset =
+ kPretenureDataOffset + kPointerSize;
static const int kDependentCodeOffset =
- kPretenureDecisionOffset + kPointerSize;
+ kPretenureCreateCountOffset + kPointerSize;
static const int kWeakNextOffset = kDependentCodeOffset + kPointerSize;
static const int kSize = kWeakNextOffset + kPointerSize;
@@ -8242,7 +8737,7 @@ class AllocationSite: public Struct {
private:
inline DependentCode::DependencyGroup ToDependencyGroup(Reason reason);
bool PretenuringDecisionMade() {
- return pretenure_decision()->value() != kUndecided;
+ return pretenure_decision() != kUndecided;
}
DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite);
@@ -8268,9 +8763,6 @@ class AllocationMemento: public Struct {
DECLARE_PRINTER(AllocationMemento)
DECLARE_VERIFIER(AllocationMemento)
- // Returns NULL if no AllocationMemento is available for object.
- static AllocationMemento* FindForJSObject(JSObject* object,
- bool in_GC = false);
static inline AllocationMemento* cast(Object* obj);
private:
@@ -8278,8 +8770,8 @@ class AllocationMemento: public Struct {
};
-// Representation of a slow alias as part of a non-strict arguments objects.
-// For fast aliases (if HasNonStrictArgumentsElements()):
+// Representation of a slow alias as part of a sloppy arguments objects.
+// For fast aliases (if HasSloppyArgumentsElements()):
// - the parameter map contains an index into the context
// - all attributes of the element have default values
// For slow aliases (if HasDictionaryArgumentsElements()):
@@ -8428,6 +8920,7 @@ class Name: public HeapObject {
// Equality operations.
inline bool Equals(Name* other);
+ inline static bool Equals(Handle<Name> one, Handle<Name> two);
// Conversion.
inline bool AsArrayIndex(uint32_t* index);
@@ -8435,8 +8928,6 @@ class Name: public HeapObject {
// Casting.
static inline Name* cast(Object* obj);
- bool IsCacheable(Isolate* isolate);
-
DECLARE_PRINTER(Name)
// Layout description.
@@ -8469,23 +8960,21 @@ class Name: public HeapObject {
static const int kArrayIndexLengthBits =
kBitsPerInt - kArrayIndexValueBits - kNofHashBitFields;
- STATIC_CHECK((kArrayIndexLengthBits > 0));
-
- static const int kArrayIndexHashLengthShift =
- kArrayIndexValueBits + kNofHashBitFields;
+ STATIC_ASSERT((kArrayIndexLengthBits > 0));
- static const int kArrayIndexHashMask = (1 << kArrayIndexHashLengthShift) - 1;
-
- static const int kArrayIndexValueMask =
- ((1 << kArrayIndexValueBits) - 1) << kHashShift;
+ class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
+ kArrayIndexValueBits> {}; // NOLINT
+ class ArrayIndexLengthBits : public BitField<unsigned int,
+ kNofHashBitFields + kArrayIndexValueBits,
+ kArrayIndexLengthBits> {}; // NOLINT
// 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_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
- static const int kContainsCachedArrayIndexMask =
- (~kMaxCachedArrayIndexLength << kArrayIndexHashLengthShift) |
+ static const unsigned int kContainsCachedArrayIndexMask =
+ (~kMaxCachedArrayIndexLength << ArrayIndexLengthBits::kShift) |
kIsNotArrayIndexMask;
// Value of empty hash field indicating that the hash is not computed.
@@ -8546,6 +9035,33 @@ class String: public Name {
public:
enum Encoding { ONE_BYTE_ENCODING, TWO_BYTE_ENCODING };
+ // 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_ASSERT((kArrayIndexLengthBits > 0));
+
+ class ArrayIndexValueBits : public BitField<unsigned int, kNofHashBitFields,
+ kArrayIndexValueBits> {}; // NOLINT
+ class ArrayIndexLengthBits : public BitField<unsigned int,
+ kNofHashBitFields + kArrayIndexValueBits,
+ kArrayIndexLengthBits> {}; // NOLINT
+
+ // 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_ASSERT(IS_POWER_OF_TWO(kMaxCachedArrayIndexLength + 1));
+
+ static const unsigned int kContainsCachedArrayIndexMask =
+ (~kMaxCachedArrayIndexLength << ArrayIndexLengthBits::kShift) |
+ kIsNotArrayIndexMask;
+
// 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
@@ -8564,28 +9080,37 @@ class String: public Name {
// true.
Vector<const uint8_t> ToOneByteVector() {
ASSERT_EQ(ASCII, state_);
- return buffer_;
+ return Vector<const uint8_t>(onebyte_start, length_);
}
// Return the two-byte content of the string. Only use if IsTwoByte()
// returns true.
Vector<const uc16> ToUC16Vector() {
ASSERT_EQ(TWO_BYTE, state_);
- return Vector<const uc16>::cast(buffer_);
+ return Vector<const uc16>(twobyte_start, length_);
+ }
+
+ uc16 Get(int i) {
+ ASSERT(i < length_);
+ ASSERT(state_ != NON_FLAT);
+ if (state_ == ASCII) return onebyte_start[i];
+ return twobyte_start[i];
}
private:
enum State { NON_FLAT, ASCII, TWO_BYTE };
// Constructors only used by String::GetFlatContent().
- 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 uint8_t> buffer_;
+ explicit FlatContent(const uint8_t* start, int length)
+ : onebyte_start(start), length_(length), state_(ASCII) { }
+ explicit FlatContent(const uc16* start, int length)
+ : twobyte_start(start), length_(length), state_(TWO_BYTE) { }
+ FlatContent() : onebyte_start(NULL), length_(0), state_(NON_FLAT) { }
+
+ union {
+ const uint8_t* onebyte_start;
+ const uc16* twobyte_start;
+ };
+ int length_;
State state_;
friend class String;
@@ -8595,6 +9120,11 @@ class String: public Name {
inline int length();
inline void set_length(int value);
+ // Get and set the length of the string using acquire loads and release
+ // stores.
+ inline int synchronized_length();
+ inline void synchronized_set_length(int 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
@@ -8618,7 +9148,7 @@ class String: public Name {
// to this method are not efficient unless the string is flat.
INLINE(uint16_t Get(int index));
- // Try to flatten the string. Checks first inline to see if it is
+ // Flattens the string. Checks first inline to see if it is
// necessary. Does nothing if the string is not a cons string.
// Flattening allocates a sequential string with the same data as
// the given string and mutates the cons string to a degenerate
@@ -8630,15 +9160,9 @@ class String: public Name {
//
// Degenerate cons strings are handled specially by the garbage
// collector (see IsShortcutCandidate).
- //
- // Use FlattenString from Handles.cc to flatten even in case an
- // allocation failure happens.
- inline MaybeObject* TryFlatten(PretenureFlag pretenure = NOT_TENURED);
- // Convenience function. Has exactly the same behavior as
- // TryFlatten(), except in the case of failure returns the original
- // string.
- inline String* TryFlattenGetString(PretenureFlag pretenure = NOT_TENURED);
+ static inline Handle<String> Flatten(Handle<String> string,
+ PretenureFlag pretenure = NOT_TENURED);
// Tries to return the content of a flat string as a structure holding either
// a flat vector of char or of uc16.
@@ -8655,13 +9179,9 @@ class String: public Name {
// ASCII and two byte string types.
bool MarkAsUndetectable();
- // Return a substring.
- MUST_USE_RESULT MaybeObject* SubString(int from,
- int to,
- PretenureFlag pretenure = NOT_TENURED);
-
// String equality operations.
inline bool Equals(String* other);
+ inline static bool Equals(Handle<String> one, Handle<String> two);
bool IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match = false);
bool IsOneByteEqualTo(Vector<const uint8_t> str);
bool IsTwoByteEqualTo(Vector<const uc16> str);
@@ -8727,18 +9247,19 @@ class String: public Name {
// Maximum number of characters to consider when trying to convert a string
// value into an array index.
static const int kMaxArrayIndexSize = 10;
- STATIC_CHECK(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
+ STATIC_ASSERT(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
// Max char codes.
static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
static const int kMaxUtf16CodeUnit = 0xffff;
+ static const uint32_t kMaxUtf16CodeUnitU = kMaxUtf16CodeUnit;
// Value of hash field containing computed hash equal to zero.
static const int kEmptyStringHash = kIsNotArrayIndexMask;
// Maximal string length.
- static const int kMaxLength = (1 << (32 - 2)) - 1;
+ static const int kMaxLength = (1 << 28) - 16;
// Max length for computing hash. For strings longer than this limit the
// string length is used as the hash value.
@@ -8805,42 +9326,26 @@ class String: public Name {
return NonOneByteStart(chars, length) >= length;
}
- // 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);
+ int offset = 0);
- 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);
- }
+ static Handle<FixedArray> CalculateLineEnds(Handle<String> string,
+ bool include_ending_line);
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 Handle<String> SlowFlatten(Handle<ConsString> cons,
+ PretenureFlag tenure);
// 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);
+ static bool SlowEquals(Handle<String> one, Handle<String> two);
+
// Slow case of AsArrayIndex.
bool SlowAsArrayIndex(uint32_t* index);
@@ -8900,9 +9405,7 @@ class SeqOneByteString: public SeqString {
// Maximal memory usage for a single sequential ASCII string.
static const int kMaxSize = 512 * MB - 1;
- // Maximal length of a single sequential ASCII string.
- // Q.v. String::kMaxLength which is the maximal size of concatenated strings.
- static const int kMaxLength = (kMaxSize - kHeaderSize);
+ STATIC_ASSERT((kMaxSize - kHeaderSize) >= String::kMaxLength);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
@@ -8942,9 +9445,8 @@ class SeqTwoByteString: public SeqString {
// Maximal memory usage for a single sequential two-byte string.
static const int kMaxSize = 512 * MB - 1;
- // Maximal length of a single sequential two-byte string.
- // Q.v. String::kMaxLength which is the maximal size of concatenated strings.
- static const int kMaxLength = (kMaxSize - kHeaderSize) / sizeof(uint16_t);
+ STATIC_ASSERT(static_cast<int>((kMaxSize - kHeaderSize)/sizeof(uint16_t)) >=
+ String::kMaxLength);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(SeqTwoByteString);
@@ -9072,7 +9574,7 @@ class ExternalString: public String {
// Return whether external string is short (data pointer is not cached).
inline bool is_short();
- STATIC_CHECK(kResourceOffset == Internals::kStringResourceOffset);
+ STATIC_ASSERT(kResourceOffset == Internals::kStringResourceOffset);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalString);
@@ -9213,57 +9715,63 @@ class ConsStringNullOp {
// 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:
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();
+ inline ConsStringIteratorOp(ConsString* cons_string, int offset = 0) {
+ Reset(cons_string, offset);
+ }
+ inline void Reset(ConsString* cons_string, int offset = 0) {
+ depth_ = 0;
+ // Next will always return NULL.
+ if (cons_string == NULL) return;
+ Initialize(cons_string, offset);
+ }
+ // Returns NULL when complete.
+ inline String* Next(int* offset_out) {
+ *offset_out = 0;
+ if (depth_ == 0) return NULL;
+ return Continue(offset_out);
+ }
private:
- // TODO(dcarney): Templatize this out for different stack sizes.
- static const unsigned kStackSize = 32;
+ static const int kStackSize = 32;
// Use a mask instead of doing modulo operations for stack wrapping.
- static const unsigned kDepthMask = kStackSize-1;
+ static const int kDepthMask = kStackSize-1;
STATIC_ASSERT(IS_POWER_OF_TWO(kStackSize));
- static inline unsigned OffsetForDepth(unsigned depth);
+ static inline int OffsetForDepth(int 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);
+ inline bool StackBlown() { return maximum_depth_ - depth_ == kStackSize; }
+ void Initialize(ConsString* cons_string, int offset);
+ String* Continue(int* offset_out);
+ String* NextLeaf(bool* blew_stack);
+ String* Search(int* offset_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_;
+ int depth_;
+ int maximum_depth_;
+ int consumed_;
DISALLOW_COPY_AND_ASSIGN(ConsStringIteratorOp);
};
-// Note: this class is not GC-safe.
class StringCharacterStream {
public:
inline StringCharacterStream(String* string,
ConsStringIteratorOp* op,
- unsigned offset = 0);
+ int 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);
+ inline void Reset(String* string, int offset = 0);
+ inline void VisitOneByteString(const uint8_t* chars, int length);
+ inline void VisitTwoByteString(const uint16_t* chars, int length);
private:
bool is_one_byte_;
@@ -9309,10 +9817,11 @@ class Oddball: public HeapObject {
DECLARE_VERIFIER(Oddball)
// Initialize the fields.
- MUST_USE_RESULT MaybeObject* Initialize(Heap* heap,
- const char* to_string,
- Object* to_number,
- byte kind);
+ static void Initialize(Isolate* isolate,
+ Handle<Oddball> oddball,
+ const char* to_string,
+ Handle<Object> to_number,
+ byte kind);
// Layout description.
static const int kToStringOffset = HeapObject::kHeaderSize;
@@ -9329,14 +9838,15 @@ class Oddball: public HeapObject {
static const byte kUndefined = 5;
static const byte kUninitialized = 6;
static const byte kOther = 7;
+ static const byte kException = 8;
typedef FixedBodyDescriptor<kToStringOffset,
kToNumberOffset + kPointerSize,
kSize> BodyDescriptor;
- STATIC_CHECK(kKindOffset == Internals::kOddballKindOffset);
- STATIC_CHECK(kNull == Internals::kNullOddballKind);
- STATIC_CHECK(kUndefined == Internals::kUndefinedOddballKind);
+ STATIC_ASSERT(kKindOffset == Internals::kOddballKindOffset);
+ STATIC_ASSERT(kNull == Internals::kNullOddballKind);
+ STATIC_ASSERT(kUndefined == Internals::kUndefinedOddballKind);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(Oddball);
@@ -9381,8 +9891,8 @@ class Cell: public HeapObject {
class PropertyCell: public Cell {
public:
// [type]: type of the global property.
- Type* type();
- void set_type(Type* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+ HeapType* type();
+ void set_type(HeapType* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// [dependent_code]: dependent code that depends on the type of the global
// property.
@@ -9397,12 +9907,11 @@ class PropertyCell: public Cell {
// Computes the new type of the cell's contents for the given value, but
// without actually modifying the 'type' field.
- static Handle<Type> UpdatedType(Handle<PropertyCell> cell,
- Handle<Object> value);
+ static Handle<HeapType> UpdatedType(Handle<PropertyCell> cell,
+ Handle<Object> value);
- void AddDependentCompilationInfo(CompilationInfo* info);
-
- void AddDependentCode(Handle<Code> code);
+ static void AddDependentCompilationInfo(Handle<PropertyCell> cell,
+ CompilationInfo* info);
// Casting.
static inline PropertyCell* cast(Object* obj);
@@ -9445,31 +9954,36 @@ class JSProxy: public JSReceiver {
// Casting.
static inline JSProxy* cast(Object* obj);
- MUST_USE_RESULT MaybeObject* GetPropertyWithHandler(
- Object* receiver,
- Name* name);
- MUST_USE_RESULT MaybeObject* GetElementWithHandler(
- Object* receiver,
+ MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<Object> receiver,
+ Handle<Name> name);
+ MUST_USE_RESULT static inline MaybeHandle<Object> GetElementWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<Object> receiver,
uint32_t index);
// If the handler defines an accessor property with a setter, invoke it.
// If it defines an accessor property without a setter, or a data property
// that is read-only, throw. In all these cases set '*done' to true,
// otherwise set it to false.
- static Handle<Object> SetPropertyViaPrototypesWithHandler(
+ MUST_USE_RESULT
+ static MaybeHandle<Object> SetPropertyViaPrototypesWithHandler(
Handle<JSProxy> proxy,
Handle<JSReceiver> receiver,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
- StrictModeFlag strict_mode,
+ StrictMode strict_mode,
bool* done);
- MUST_USE_RESULT PropertyAttributes GetPropertyAttributeWithHandler(
- JSReceiver* receiver,
- Name* name);
- MUST_USE_RESULT PropertyAttributes GetElementAttributeWithHandler(
- JSReceiver* receiver,
+ static PropertyAttributes GetPropertyAttributesWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<Object> receiver,
+ Handle<Name> name);
+ static PropertyAttributes GetElementAttributeWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<JSReceiver> receiver,
uint32_t index);
// Turn the proxy into an (empty) JSObject.
@@ -9480,10 +9994,12 @@ class JSProxy: public JSReceiver {
// Invoke a trap by name. If the trap does not exist on this's handler,
// but derived_trap is non-NULL, invoke that instead. May cause GC.
- Handle<Object> CallTrap(const char* name,
- Handle<Object> derived_trap,
- int argc,
- Handle<Object> args[]);
+ MUST_USE_RESULT static MaybeHandle<Object> CallTrap(
+ Handle<JSProxy> proxy,
+ const char* name,
+ Handle<Object> derived_trap,
+ int argc,
+ Handle<Object> args[]);
// Dispatched behavior.
DECLARE_PRINTER(JSProxy)
@@ -9499,7 +10015,7 @@ class JSProxy: public JSReceiver {
static const int kHeaderSize = kPaddingOffset;
static const int kPaddingSize = kSize - kPaddingOffset;
- STATIC_CHECK(kPaddingSize >= 0);
+ STATIC_ASSERT(kPaddingSize >= 0);
typedef FixedBodyDescriptor<kHandlerOffset,
kPaddingOffset,
@@ -9508,31 +10024,36 @@ class JSProxy: public JSReceiver {
private:
friend class JSReceiver;
- static Handle<Object> SetPropertyWithHandler(Handle<JSProxy> proxy,
- Handle<JSReceiver> receiver,
- Handle<Name> name,
- Handle<Object> value,
- PropertyAttributes attributes,
- StrictModeFlag strict_mode);
- static Handle<Object> SetElementWithHandler(Handle<JSProxy> proxy,
- Handle<JSReceiver> receiver,
- uint32_t index,
- Handle<Object> value,
- StrictModeFlag strict_mode);
+ MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<JSReceiver> receiver,
+ Handle<Name> name,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ StrictMode strict_mode);
+ MUST_USE_RESULT static inline MaybeHandle<Object> SetElementWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<JSReceiver> receiver,
+ uint32_t index,
+ Handle<Object> value,
+ StrictMode strict_mode);
static bool HasPropertyWithHandler(Handle<JSProxy> proxy, Handle<Name> name);
- static bool HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index);
+ static inline bool HasElementWithHandler(Handle<JSProxy> proxy,
+ uint32_t index);
- static Handle<Object> DeletePropertyWithHandler(Handle<JSProxy> proxy,
- Handle<Name> name,
- DeleteMode mode);
- static Handle<Object> DeleteElementWithHandler(Handle<JSProxy> proxy,
- uint32_t index,
- DeleteMode mode);
+ MUST_USE_RESULT static MaybeHandle<Object> DeletePropertyWithHandler(
+ Handle<JSProxy> proxy,
+ Handle<Name> name,
+ DeleteMode mode);
+ MUST_USE_RESULT static MaybeHandle<Object> DeleteElementWithHandler(
+ Handle<JSProxy> proxy,
+ uint32_t index,
+ DeleteMode mode);
MUST_USE_RESULT Object* GetIdentityHash();
- static Handle<Object> GetOrCreateIdentityHash(Handle<JSProxy> proxy);
+ static Handle<Smi> GetOrCreateIdentityHash(Handle<JSProxy> proxy);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
};
@@ -9560,7 +10081,7 @@ class JSFunctionProxy: public JSProxy {
static const int kSize = JSFunction::kSize;
static const int kPaddingSize = kSize - kPaddingOffset;
- STATIC_CHECK(kPaddingSize >= 0);
+ STATIC_ASSERT(kPaddingSize >= 0);
typedef FixedBodyDescriptor<kHandlerOffset,
kConstructTrapOffset + kPointerSize,
@@ -9613,6 +10134,97 @@ class JSMap: public JSObject {
};
+// OrderedHashTableIterator is an iterator that iterates over the keys and
+// values of an OrderedHashTable.
+//
+// The iterator has a reference to the underlying OrderedHashTable data,
+// [table], as well as the current [index] the iterator is at.
+//
+// When the OrderedHashTable is rehashed it adds a reference from the old table
+// to the new table as well as storing enough data about the changes so that the
+// iterator [index] can be adjusted accordingly.
+//
+// When the [Next] result from the iterator is requested, the iterator checks if
+// there is a newer table that it needs to transition to.
+template<class Derived, class TableType>
+class OrderedHashTableIterator: public JSObject {
+ public:
+ // [table]: the backing hash table mapping keys to values.
+ DECL_ACCESSORS(table, Object)
+
+ // [index]: The index into the data table.
+ DECL_ACCESSORS(index, Smi)
+
+ // [kind]: The kind of iteration this is. One of the [Kind] enum values.
+ DECL_ACCESSORS(kind, Smi)
+
+#ifdef OBJECT_PRINT
+ void OrderedHashTableIteratorPrint(FILE* out);
+#endif
+
+ static const int kTableOffset = JSObject::kHeaderSize;
+ static const int kIndexOffset = kTableOffset + kPointerSize;
+ static const int kKindOffset = kIndexOffset + kPointerSize;
+ static const int kSize = kKindOffset + kPointerSize;
+
+ enum Kind {
+ kKindKeys = 1,
+ kKindValues = 2,
+ kKindEntries = 3
+ };
+
+ // Returns an iterator result object: {value: any, done: boolean} and moves
+ // the index to the next valid entry. Closes the iterator if moving past the
+ // end.
+ static Handle<JSObject> Next(Handle<Derived> iterator);
+
+ private:
+ // Transitions the iterator to the non obsolote backing store. This is a NOP
+ // if the [table] is not obsolete.
+ void Transition();
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator);
+};
+
+
+class JSSetIterator: public OrderedHashTableIterator<JSSetIterator,
+ OrderedHashSet> {
+ public:
+ // Dispatched behavior.
+ DECLARE_PRINTER(JSSetIterator)
+ DECLARE_VERIFIER(JSSetIterator)
+
+ // Casting.
+ static inline JSSetIterator* cast(Object* obj);
+
+ static Handle<Object> ValueForKind(
+ Handle<JSSetIterator> iterator,
+ int entry_index);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator);
+};
+
+
+class JSMapIterator: public OrderedHashTableIterator<JSMapIterator,
+ OrderedHashMap> {
+ public:
+ // Dispatched behavior.
+ DECLARE_PRINTER(JSMapIterator)
+ DECLARE_VERIFIER(JSMapIterator)
+
+ // Casting.
+ static inline JSMapIterator* cast(Object* obj);
+
+ static Handle<Object> ValueForKind(
+ Handle<JSMapIterator> iterator,
+ int entry_index);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator);
+};
+
+
// Base class for both JSWeakMap and JSWeakSet
class JSWeakCollection: public JSObject {
public:
@@ -9760,6 +10372,8 @@ class JSTypedArray: public JSArrayBufferView {
ExternalArrayType type();
size_t element_size();
+ Handle<JSArrayBuffer> GetBuffer();
+
// Dispatched behavior.
DECLARE_PRINTER(JSTypedArray)
DECLARE_VERIFIER(JSTypedArray)
@@ -9771,6 +10385,9 @@ class JSTypedArray: public JSArrayBufferView {
kSize + v8::ArrayBufferView::kInternalFieldCount * kPointerSize;
private:
+ static Handle<JSArrayBuffer> MaterializeArrayBuffer(
+ Handle<JSTypedArray> typed_array);
+
DISALLOW_IMPLICIT_CONSTRUCTORS(JSTypedArray);
};
@@ -9824,7 +10441,7 @@ class Foreign: public HeapObject {
static const int kForeignAddressOffset = HeapObject::kHeaderSize;
static const int kSize = kForeignAddressOffset + kPointerSize;
- STATIC_CHECK(kForeignAddressOffset == Internals::kForeignAddressOffset);
+ STATIC_ASSERT(kForeignAddressOffset == Internals::kForeignAddressOffset);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(Foreign);
@@ -9849,28 +10466,38 @@ class JSArray: public JSObject {
uint32_t index,
Handle<Object> value);
- MUST_USE_RESULT MaybeObject* JSArrayUpdateLengthFromIndex(uint32_t index,
- Object* value);
+ static bool IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map);
+ static bool WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index);
+ static MaybeHandle<Object> ReadOnlyLengthError(Handle<JSArray> array);
// 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, int length = 0);
+ static void Initialize(Handle<JSArray> array, 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);
+ MUST_USE_RESULT static MaybeHandle<Object> SetElementsLength(
+ Handle<JSArray> array,
+ Handle<Object> length);
// Set the content of the array to the content of storage.
- MUST_USE_RESULT inline MaybeObject* SetContent(FixedArrayBase* storage);
+ static inline void SetContent(Handle<JSArray> array,
+ Handle<FixedArrayBase> storage);
// Casting.
static inline JSArray* cast(Object* obj);
- // Uses handles. Ensures that the fixed array backing the JSArray has at
+ // Ensures that the fixed array backing the JSArray has at
// least the stated size.
- inline void EnsureSize(int minimum_size_of_backing_fixed_array);
+ static inline void EnsureSize(Handle<JSArray> array,
+ int minimum_size_of_backing_fixed_array);
+
+ // Expand the fixed array backing of a fast-case JSArray to at least
+ // the requested size.
+ static void Expand(Handle<JSArray> array,
+ int minimum_size_of_backing_fixed_array);
// Dispatched behavior.
DECLARE_PRINTER(JSArray)
@@ -9884,10 +10511,6 @@ class JSArray: public JSObject {
static const int kSize = kLengthOffset + kPointerSize;
private:
- // Expand the fixed array backing of a fast-case JSArray to at least
- // the requested size.
- void Expand(int minimum_size_of_backing_fixed_array);
-
DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray);
};
@@ -9928,9 +10551,6 @@ class AccessorInfo: public Struct {
inline bool all_can_write();
inline void set_all_can_write(bool value);
- inline bool prohibits_overwriting();
- inline void set_prohibits_overwriting(bool value);
-
inline PropertyAttributes property_attributes();
inline void set_property_attributes(PropertyAttributes attributes);
@@ -9957,8 +10577,7 @@ class AccessorInfo: public Struct {
// Bit positions in flag.
static const int kAllCanReadBit = 0;
static const int kAllCanWriteBit = 1;
- static const int kProhibitsOverwritingBit = 2;
- class AttributesField: public BitField<PropertyAttributes, 3, 3> {};
+ class AttributesField: public BitField<PropertyAttributes, 2, 3> {};
DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
};
@@ -10080,7 +10699,7 @@ class DeclaredAccessorInfo: public AccessorInfo {
// 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.
+// a new value is added to the derived object when the property is set.
// This shadows the accessor in the prototype.
class ExecutableAccessorInfo: public AccessorInfo {
public:
@@ -10099,6 +10718,8 @@ class ExecutableAccessorInfo: public AccessorInfo {
static const int kDataOffset = kSetterOffset + kPointerSize;
static const int kSize = kDataOffset + kPointerSize;
+ inline void clear_setter();
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ExecutableAccessorInfo);
};
@@ -10121,7 +10742,6 @@ class AccessorPair: public Struct {
inline void set_access_flags(v8::AccessControl access_control);
inline bool all_can_read();
inline bool all_can_write();
- inline bool prohibits_overwriting();
static inline AccessorPair* cast(Object* obj);
@@ -10164,7 +10784,6 @@ class AccessorPair: public Struct {
private:
static const int kAllCanReadBit = 0;
static const int kAllCanWriteBit = 1;
- static const int kProhibitsOverwritingBit = 2;
// Strangely enough, in addition to functions and harmony proxies, the spec
// requires us to consider undefined as a kind of accessor, too:
@@ -10393,7 +11012,6 @@ class TypeSwitchInfo: public Struct {
};
-#ifdef ENABLE_DEBUGGER_SUPPORT
// The DebugInfo class holds additional information for a function being
// debugged.
class DebugInfo: public Struct {
@@ -10443,6 +11061,8 @@ class DebugInfo: public Struct {
kActiveBreakPointsCountIndex + kPointerSize;
static const int kSize = kBreakPointsStateIndex + kPointerSize;
+ static const int kEstimatedNofBreakPointsInFunction = 16;
+
private:
static const int kNoBreakPointInfo = -1;
@@ -10497,7 +11117,6 @@ class BreakPointInfo: public Struct {
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(BreakPointInfo);
};
-#endif // ENABLE_DEBUGGER_SUPPORT
#undef DECL_BOOLEAN_ACCESSORS
@@ -10508,6 +11127,7 @@ class BreakPointInfo: public Struct {
V(kStringTable, "string_table", "(Internalized strings)") \
V(kExternalStringsTable, "external_strings_table", "(External strings)") \
V(kStrongRootList, "strong_root_list", "(Strong roots)") \
+ V(kSmiRootList, "smi_root_list", "(Smi roots)") \
V(kInternalizedString, "internalized_string", "(Internal string)") \
V(kBootstrapper, "bootstrapper", "(Bootstrapper)") \
V(kTop, "top", "(Isolate)") \
@@ -10547,6 +11167,9 @@ class ObjectVisitor BASE_EMBEDDED {
// Handy shorthand for visiting a single pointer.
virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
+ // Visit weak next_code_link in Code object.
+ virtual void VisitNextCodeLink(Object** p) { VisitPointers(p, p + 1); }
+
// To allow lazy clearing of inline caches the visitor has
// a rich interface for iterating over Code objects..