Upgrade V8 to version 4.9.385.28
https://chromium.googlesource.com/v8/v8/+/4.9.385.28
FPIIM-449
Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/globals.h b/src/globals.h
index 52ec2aa..67bdb63 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -8,6 +8,8 @@
#include <stddef.h>
#include <stdint.h>
+#include <ostream>
+
#include "src/base/build_config.h"
#include "src/base/logging.h"
#include "src/base/macros.h"
@@ -22,23 +24,12 @@
# define V8_INFINITY std::numeric_limits<double>::infinity()
#elif V8_LIBC_MSVCRT
# define V8_INFINITY HUGE_VAL
+#elif V8_OS_AIX
+#define V8_INFINITY (__builtin_inff())
#else
# define V8_INFINITY INFINITY
#endif
-#if V8_TARGET_ARCH_IA32 || (V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_32_BIT) || \
- V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
- V8_TARGET_ARCH_MIPS64
-#define V8_TURBOFAN_BACKEND 1
-#else
-#define V8_TURBOFAN_BACKEND 0
-#endif
-#if V8_TURBOFAN_BACKEND
-#define V8_TURBOFAN_TARGET 1
-#else
-#define V8_TURBOFAN_TARGET 0
-#endif
-
namespace v8 {
namespace base {
@@ -59,6 +50,9 @@
#if (V8_TARGET_ARCH_ARM && !V8_HOST_ARCH_ARM)
#define USE_SIMULATOR 1
#endif
+#if (V8_TARGET_ARCH_PPC && !V8_HOST_ARCH_PPC)
+#define USE_SIMULATOR 1
+#endif
#if (V8_TARGET_ARCH_MIPS && !V8_HOST_ARCH_MIPS)
#define USE_SIMULATOR 1
#endif
@@ -67,8 +61,13 @@
#endif
#endif
-// Determine whether the architecture uses an out-of-line constant pool.
-#define V8_OOL_CONSTANT_POOL 0
+// Determine whether the architecture uses an embedded constant pool
+// (contiguous constant pool embedded in code object).
+#if V8_TARGET_ARCH_PPC
+#define V8_EMBEDDED_CONSTANT_POOL 1
+#else
+#define V8_EMBEDDED_CONSTANT_POOL 0
+#endif
#ifdef V8_TARGET_ARCH_ARM
// Set stack limit lower for ARM than for other architectures because
@@ -83,8 +82,8 @@
// Determine whether double field unboxing feature is enabled.
-#if (V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64)
-#define V8_DOUBLE_FIELDS_UNBOXING 0
+#if V8_TARGET_ARCH_64_BIT
+#define V8_DOUBLE_FIELDS_UNBOXING 1
#else
#define V8_DOUBLE_FIELDS_UNBOXING 0
#endif
@@ -117,6 +116,7 @@
const int kIntSize = sizeof(int); // NOLINT
const int kInt32Size = sizeof(int32_t); // NOLINT
const int kInt64Size = sizeof(int64_t); // NOLINT
+const int kFloatSize = sizeof(float); // NOLINT
const int kDoubleSize = sizeof(double); // NOLINT
const int kIntptrSize = sizeof(intptr_t); // NOLINT
const int kPointerSize = sizeof(void*); // NOLINT
@@ -135,7 +135,14 @@
const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000);
const uintptr_t kUintptrAllBitsSet = V8_UINT64_C(0xFFFFFFFFFFFFFFFF);
const bool kRequiresCodeRange = true;
+#if V8_TARGET_ARCH_MIPS64
+// To use pseudo-relative jumps such as j/jal instructions which have 28-bit
+// encoded immediate, the addresses have to be in range of 256MB aligned
+// region. Used only for large object space.
+const size_t kMaximalCodeRangeSize = 256 * MB;
+#else
const size_t kMaximalCodeRangeSize = 512 * MB;
+#endif
#if V8_OS_WIN
const size_t kMinimumCodeRangeSize = 4 * MB;
const size_t kReservedCodeRangePages = 1;
@@ -190,6 +197,8 @@
const int kOneByteSize = kCharSize;
const int kUC16Size = sizeof(uc16); // NOLINT
+// 128 bit SIMD value size.
+const int kSimd128Size = 16;
// Round up n to be a multiple of sz, where sz is a power of 2.
#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
@@ -208,6 +217,20 @@
}
+// Determine whether the architecture uses function descriptors
+// which provide a level of indirection between the function pointer
+// and the function entrypoint.
+#if V8_HOST_ARCH_PPC && \
+ (V8_OS_AIX || (V8_TARGET_ARCH_PPC64 && V8_TARGET_BIG_ENDIAN))
+#define USES_FUNCTION_DESCRIPTORS 1
+#define FUNCTION_ENTRYPOINT_ADDRESS(f) \
+ (reinterpret_cast<v8::internal::Address*>( \
+ &(reinterpret_cast<intptr_t*>(f)[0])))
+#else
+#define USES_FUNCTION_DESCRIPTORS 0
+#endif
+
+
// -----------------------------------------------------------------------------
// Forward declarations for frequently used classes
// (sorted alphabetically)
@@ -220,7 +243,90 @@
// The Strict Mode (ECMA-262 5th edition, 4.2.2).
-enum StrictMode { SLOPPY, STRICT };
+enum LanguageMode {
+ // LanguageMode is expressed as a bitmask. Descriptions of the bits:
+ STRICT_BIT = 1 << 0,
+ STRONG_BIT = 1 << 1,
+ LANGUAGE_END,
+
+ // Shorthands for some common language modes.
+ SLOPPY = 0,
+ STRICT = STRICT_BIT,
+ STRONG = STRICT_BIT | STRONG_BIT
+};
+
+
+inline std::ostream& operator<<(std::ostream& os, const LanguageMode& mode) {
+ switch (mode) {
+ case SLOPPY:
+ return os << "sloppy";
+ case STRICT:
+ return os << "strict";
+ case STRONG:
+ return os << "strong";
+ default:
+ return os << "unknown";
+ }
+}
+
+
+inline bool is_sloppy(LanguageMode language_mode) {
+ return (language_mode & STRICT_BIT) == 0;
+}
+
+
+inline bool is_strict(LanguageMode language_mode) {
+ return language_mode & STRICT_BIT;
+}
+
+
+inline bool is_strong(LanguageMode language_mode) {
+ return language_mode & STRONG_BIT;
+}
+
+
+inline bool is_valid_language_mode(int language_mode) {
+ return language_mode == SLOPPY || language_mode == STRICT ||
+ language_mode == STRONG;
+}
+
+
+inline LanguageMode construct_language_mode(bool strict_bit, bool strong_bit) {
+ int language_mode = 0;
+ if (strict_bit) language_mode |= STRICT_BIT;
+ if (strong_bit) language_mode |= STRONG_BIT;
+ DCHECK(is_valid_language_mode(language_mode));
+ return static_cast<LanguageMode>(language_mode);
+}
+
+
+// Strong mode behaviour must sometimes be signalled by a two valued enum where
+// caching is involved, to prevent sloppy and strict mode from being incorrectly
+// differentiated.
+enum class Strength : bool {
+ WEAK, // sloppy, strict behaviour
+ STRONG // strong behaviour
+};
+
+
+inline bool is_strong(Strength strength) {
+ return strength == Strength::STRONG;
+}
+
+
+inline std::ostream& operator<<(std::ostream& os, const Strength& strength) {
+ return os << (is_strong(strength) ? "strong" : "weak");
+}
+
+
+inline Strength strength(LanguageMode language_mode) {
+ return is_strong(language_mode) ? Strength::STRONG : Strength::WEAK;
+}
+
+
+inline size_t hash_value(Strength strength) {
+ return static_cast<size_t>(strength);
+}
// Mask for the sign bit in a smi.
@@ -238,6 +344,10 @@
const intptr_t kDoubleAlignment = 8;
const intptr_t kDoubleAlignmentMask = kDoubleAlignment - 1;
+// Desired alignment for 128 bit SIMD values.
+const intptr_t kSimd128Alignment = 16;
+const intptr_t kSimd128AlignmentMask = kSimd128Alignment - 1;
+
// Desired alignment for generated code is 32 bytes (to improve cache line
// utilization).
const int kCodeAlignmentBits = 5;
@@ -304,7 +414,6 @@
class CodeStub;
class Context;
class Debug;
-class Debugger;
class DebugInfo;
class Descriptor;
class DescriptorArray;
@@ -316,6 +425,7 @@
class SeededNumberDictionary;
class UnseededNumberDictionary;
class NameDictionary;
+class GlobalDictionary;
template <typename T> class MaybeHandle;
template <typename T> class Handle;
class Heap;
@@ -328,7 +438,6 @@
class JSFunction;
class JSObject;
class LargeObjectSpace;
-class LookupResult;
class MacroAssembler;
class Map;
class MapSpace;
@@ -336,18 +445,19 @@
class NewSpace;
class Object;
class OldSpace;
+class ParameterCount;
class Foreign;
class Scope;
class ScopeInfo;
class Script;
class Smi;
template <typename Config, class Allocator = FreeStoreAllocationPolicy>
- class SplayTree;
+class SplayTree;
class String;
class Symbol;
class Name;
class Struct;
-class Symbol;
+class TypeFeedbackVector;
class Variable;
class RelocInfo;
class Deserializer;
@@ -364,23 +474,26 @@
// consecutive.
// Keep this enum in sync with the ObjectSpace enum in v8.h
enum AllocationSpace {
- NEW_SPACE, // Semispaces collected with copying collector.
- OLD_POINTER_SPACE, // May contain pointers to new space.
- OLD_DATA_SPACE, // Must not have pointers to new space.
- CODE_SPACE, // No pointers to new space, marked executable.
- MAP_SPACE, // Only and all map objects.
- CELL_SPACE, // Only and all cell objects.
- PROPERTY_CELL_SPACE, // Only and all global property cell objects.
- LO_SPACE, // Promoted large objects.
+ NEW_SPACE, // Semispaces collected with copying collector.
+ OLD_SPACE, // May contain pointers to new space.
+ CODE_SPACE, // No pointers to new space, marked executable.
+ MAP_SPACE, // Only and all map objects.
+ LO_SPACE, // Promoted large objects.
FIRST_SPACE = NEW_SPACE,
LAST_SPACE = LO_SPACE,
- FIRST_PAGED_SPACE = OLD_POINTER_SPACE,
- LAST_PAGED_SPACE = PROPERTY_CELL_SPACE
+ FIRST_PAGED_SPACE = OLD_SPACE,
+ LAST_PAGED_SPACE = MAP_SPACE
};
const int kSpaceTagSize = 3;
const int kSpaceTagMask = (1 << kSpaceTagSize) - 1;
+enum AllocationAlignment {
+ kWordAligned,
+ kDoubleAligned,
+ kDoubleUnaligned,
+ kSimd128Unaligned
+};
// A flag that indicates whether objects should be pretenured when
// allocated (allocated directly into the old generation) or not
@@ -388,6 +501,17 @@
// allows).
enum PretenureFlag { NOT_TENURED, TENURED };
+inline std::ostream& operator<<(std::ostream& os, const PretenureFlag& flag) {
+ switch (flag) {
+ case NOT_TENURED:
+ return os << "NotTenured";
+ case TENURED:
+ return os << "Tenured";
+ }
+ UNREACHABLE();
+ return os;
+}
+
enum MinimumCapacity {
USE_DEFAULT_MINIMUM_CAPACITY,
USE_CUSTOM_MINIMUM_CAPACITY
@@ -407,17 +531,28 @@
// Flag indicating whether code is built into the VM (one of the natives files).
enum NativesFlag { NOT_NATIVES_CODE, NATIVES_CODE };
+// JavaScript defines two kinds of 'nil'.
+enum NilValue { kNullValue, kUndefinedValue };
+
+// ParseRestriction is used to restrict the set of valid statements in a
+// unit of compilation. Restriction violations cause a syntax error.
+enum ParseRestriction {
+ NO_PARSE_RESTRICTION, // All expressions are allowed.
+ ONLY_SINGLE_FUNCTION_LITERAL // Only a single FunctionLiteral expression.
+};
// A CodeDesc describes a buffer holding instructions and relocation
// information. The instructions start at the beginning of the buffer
// and grow forward, the relocation information starts at the end of
-// the buffer and grows backward.
+// the buffer and grows backward. A constant pool may exist at the
+// end of the instructions.
//
-// |<--------------- buffer_size ---------------->|
-// |<-- instr_size -->| |<-- reloc_size -->|
-// +==================+========+==================+
-// | instructions | free | reloc info |
-// +==================+========+==================+
+// |<--------------- buffer_size ----------------------------------->|
+// |<------------- instr_size ---------->| |<-- reloc_size -->|
+// | |<- const_pool_size ->| |
+// +=====================================+========+==================+
+// | instructions | data | free | reloc info |
+// +=====================================+========+==================+
// ^
// |
// buffer
@@ -427,15 +562,11 @@
int buffer_size;
int instr_size;
int reloc_size;
+ int constant_pool_size;
Assembler* origin;
};
-// Callback function used for iterating objects in heap spaces,
-// for example, scanning heap objects.
-typedef int (*HeapObjectCallback)(HeapObject* obj);
-
-
// Callback function used for checking constraints when copying/relocating
// objects. Returns true if an object can be copied/relocated from its
// old_addr to a new_addr.
@@ -464,27 +595,7 @@
// A generic handler is installed and no extra typefeedback is recorded.
GENERIC,
// Special state for debug break or step in prepare stubs.
- DEBUG_STUB,
- // Type-vector-based ICs have a default state, with the full calculation
- // of IC state only determined by a look at the IC and the typevector
- // together.
- DEFAULT
-};
-
-
-enum CallFunctionFlags {
- NO_CALL_FUNCTION_FLAGS,
- CALL_AS_METHOD,
- // Always wrap the receiver and call to the JSFunction. Only use this flag
- // both the receiver type and the target method are statically known.
- WRAP_AND_CALL
-};
-
-
-enum CallConstructorFlags {
- NO_CALL_CONSTRUCTOR_FLAGS,
- // The call target is cached in the instruction stream.
- RECORD_CONSTRUCTOR_TARGET
+ DEBUG_STUB
};
@@ -562,9 +673,6 @@
#define HAS_SMI_TAG(value) \
((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag)
-#define HAS_FAILURE_TAG(value) \
- ((reinterpret_cast<intptr_t>(value) & kFailureTagMask) == kFailureTag)
-
// OBJECT_POINTER_ALIGN returns the value aligned as a HeapObject pointer
#define OBJECT_POINTER_ALIGN(value) \
(((value) + kObjectAlignmentMask) & ~kObjectAlignmentMask)
@@ -577,25 +685,9 @@
#define CODE_POINTER_ALIGN(value) \
(((value) + kCodeAlignmentMask) & ~kCodeAlignmentMask)
-// Support for tracking C++ memory allocation. Insert TRACK_MEMORY("Fisk")
-// inside a C++ class and new and delete will be overloaded so logging is
-// performed.
-// This file (globals.h) is included before log.h, so we use direct calls to
-// the Logger rather than the LOG macro.
-#ifdef DEBUG
-#define TRACK_MEMORY(name) \
- void* operator new(size_t size) { \
- void* result = ::operator new(size); \
- Logger::NewEventStatic(name, result, size); \
- return result; \
- } \
- void operator delete(void* object) { \
- Logger::DeleteEventStatic(name, object); \
- ::operator delete(object); \
- }
-#else
-#define TRACK_MEMORY(name)
-#endif
+// DOUBLE_POINTER_ALIGN returns the value algined for double pointers.
+#define DOUBLE_POINTER_ALIGN(value) \
+ (((value) + kDoubleAlignmentMask) & ~kDoubleAlignmentMask)
// CPU feature flags.
@@ -606,6 +698,11 @@
SAHF,
AVX,
FMA3,
+ BMI1,
+ BMI2,
+ LZCNT,
+ POPCNT,
+ ATOM,
// ARM
VFP3,
ARMv7,
@@ -625,10 +722,39 @@
// ARM64
ALWAYS_ALIGN_CSP,
COHERENT_CACHE,
+ // PPC
+ FPR_GPR_MOV,
+ LWSYNC,
+ ISELECT,
NUMBER_OF_CPU_FEATURES
};
+// Defines hints about receiver values based on structural knowledge.
+enum class ConvertReceiverMode : unsigned {
+ kNullOrUndefined, // Guaranteed to be null or undefined.
+ kNotNullOrUndefined, // Guaranteed to never be null or undefined.
+ kAny // No specific knowledge about receiver.
+};
+
+inline size_t hash_value(ConvertReceiverMode mode) {
+ return bit_cast<unsigned>(mode);
+}
+
+inline std::ostream& operator<<(std::ostream& os, ConvertReceiverMode mode) {
+ switch (mode) {
+ case ConvertReceiverMode::kNullOrUndefined:
+ return os << "NULL_OR_UNDEFINED";
+ case ConvertReceiverMode::kNotNullOrUndefined:
+ return os << "NOT_NULL_OR_UNDEFINED";
+ case ConvertReceiverMode::kAny:
+ return os << "ANY";
+ }
+ UNREACHABLE();
+ return os;
+}
+
+
// Used to specify if a macro instruction must perform a smi check on tagged
// values.
enum SmiCheckType {
@@ -644,19 +770,25 @@
SCRIPT_SCOPE, // The top-level scope for a script or a top-level eval.
CATCH_SCOPE, // The scope introduced by catch.
BLOCK_SCOPE, // The scope introduced by a new block.
- WITH_SCOPE, // The scope introduced by with.
- ARROW_SCOPE // The top-level scope for an arrow function literal.
+ WITH_SCOPE // The scope introduced by with.
};
-
-const uint32_t kHoleNanUpper32 = 0x7FFFFFFF;
-const uint32_t kHoleNanLower32 = 0xFFFFFFFF;
-const uint32_t kNaNOrInfinityLowerBoundUpper32 = 0x7FF00000;
+// The mips architecture prior to revision 5 has inverted encoding for sNaN.
+#if (V8_TARGET_ARCH_MIPS && !defined(_MIPS_ARCH_MIPS32R6)) || \
+ (V8_TARGET_ARCH_MIPS64 && !defined(_MIPS_ARCH_MIPS64R6))
+const uint32_t kHoleNanUpper32 = 0xFFFF7FFF;
+const uint32_t kHoleNanLower32 = 0xFFFF7FFF;
+#else
+const uint32_t kHoleNanUpper32 = 0xFFF7FFFF;
+const uint32_t kHoleNanLower32 = 0xFFF7FFFF;
+#endif
const uint64_t kHoleNanInt64 =
(static_cast<uint64_t>(kHoleNanUpper32) << 32) | kHoleNanLower32;
-const uint64_t kLastNonNaNInt64 =
- (static_cast<uint64_t>(kNaNOrInfinityLowerBoundUpper32) << 32);
+
+
+// ES6 section 20.1.2.6 Number.MAX_SAFE_INTEGER
+const double kMaxSafeInteger = 9007199254740991.0; // 2^53-1
// The order of this enum has to be kept in sync with the predicates below.
@@ -670,12 +802,9 @@
CONST, // declared via 'const' declarations
- MODULE, // declared via 'module' declaration (last lexical)
+ IMPORT, // declared via 'import' declarations (last lexical)
// Variables introduced by the compiler:
- INTERNAL, // like VAR, but not user-visible (may or may not
- // be in a context)
-
TEMPORARY, // temporary variables (not user-visible), stack-allocated
// unless the scope as a whole has forced context allocation
@@ -699,20 +828,54 @@
inline bool IsDeclaredVariableMode(VariableMode mode) {
- return mode >= VAR && mode <= MODULE;
+ return mode >= VAR && mode <= IMPORT;
}
inline bool IsLexicalVariableMode(VariableMode mode) {
- return mode >= LET && mode <= MODULE;
+ return mode >= LET && mode <= IMPORT;
}
inline bool IsImmutableVariableMode(VariableMode mode) {
- return (mode >= CONST && mode <= MODULE) || mode == CONST_LEGACY;
+ return mode == CONST || mode == CONST_LEGACY || mode == IMPORT;
}
+enum class VariableLocation {
+ // Before and during variable allocation, a variable whose location is
+ // not yet determined. After allocation, a variable looked up as a
+ // property on the global object (and possibly absent). name() is the
+ // variable name, index() is invalid.
+ UNALLOCATED,
+
+ // A slot in the parameter section on the stack. index() is the
+ // parameter index, counting left-to-right. The receiver is index -1;
+ // the first parameter is index 0.
+ PARAMETER,
+
+ // A slot in the local section on the stack. index() is the variable
+ // index in the stack frame, starting at 0.
+ LOCAL,
+
+ // An indexed slot in a heap context. index() is the variable index in
+ // the context object on the heap, starting at 0. scope() is the
+ // corresponding scope.
+ CONTEXT,
+
+ // An indexed slot in a script context that contains a respective global
+ // property cell. name() is the variable name, index() is the variable
+ // index in the context object on the heap, starting at 0. scope() is the
+ // corresponding script scope.
+ GLOBAL,
+
+ // A named slot in a heap context. name() is the variable name in the
+ // context object on the heap, with lookup starting at the current
+ // context. index() is invalid.
+ LOOKUP
+};
+
+
// ES6 Draft Rev3 10.2 specifies declarative environment records with mutable
// and immutable bindings that can be in two states: initialized and
// uninitialized. In ES5 only immutable bindings have these two states. When
@@ -753,6 +916,10 @@
enum MaybeAssignedFlag { kNotAssigned, kMaybeAssigned };
+// Serialized in PreparseData, so numeric values should not be changed.
+enum ParseErrorType { kSyntaxError = 0, kReferenceError = 1 };
+
+
enum ClearExceptionFlag {
KEEP_EXCEPTION,
CLEAR_EXCEPTION
@@ -770,11 +937,23 @@
enum FunctionKind {
kNormalFunction = 0,
- kArrowFunction = 1,
- kGeneratorFunction = 2,
- kConciseMethod = 4,
+ kArrowFunction = 1 << 0,
+ kGeneratorFunction = 1 << 1,
+ kConciseMethod = 1 << 2,
kConciseGeneratorMethod = kGeneratorFunction | kConciseMethod,
- kDefaultConstructor = 8
+ kAccessorFunction = 1 << 3,
+ kDefaultConstructor = 1 << 4,
+ kSubclassConstructor = 1 << 5,
+ kBaseConstructor = 1 << 6,
+ kInObjectLiteral = 1 << 7,
+ kDefaultBaseConstructor = kDefaultConstructor | kBaseConstructor,
+ kDefaultSubclassConstructor = kDefaultConstructor | kSubclassConstructor,
+ kClassConstructor =
+ kBaseConstructor | kSubclassConstructor | kDefaultConstructor,
+ kConciseMethodInObjectLiteral = kConciseMethod | kInObjectLiteral,
+ kConciseGeneratorMethodInObjectLiteral =
+ kConciseGeneratorMethod | kInObjectLiteral,
+ kAccessorFunctionInObjectLiteral = kAccessorFunction | kInObjectLiteral,
};
@@ -784,7 +963,14 @@
kind == FunctionKind::kGeneratorFunction ||
kind == FunctionKind::kConciseMethod ||
kind == FunctionKind::kConciseGeneratorMethod ||
- kind == FunctionKind::kDefaultConstructor;
+ kind == FunctionKind::kAccessorFunction ||
+ kind == FunctionKind::kDefaultBaseConstructor ||
+ kind == FunctionKind::kDefaultSubclassConstructor ||
+ kind == FunctionKind::kBaseConstructor ||
+ kind == FunctionKind::kSubclassConstructor ||
+ kind == FunctionKind::kConciseMethodInObjectLiteral ||
+ kind == FunctionKind::kConciseGeneratorMethodInObjectLiteral ||
+ kind == FunctionKind::kAccessorFunctionInObjectLiteral;
}
@@ -806,13 +992,58 @@
}
+inline bool IsAccessorFunction(FunctionKind kind) {
+ DCHECK(IsValidFunctionKind(kind));
+ return kind & FunctionKind::kAccessorFunction;
+}
+
+
inline bool IsDefaultConstructor(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return kind & FunctionKind::kDefaultConstructor;
}
-} } // namespace v8::internal
+inline bool IsBaseConstructor(FunctionKind kind) {
+ DCHECK(IsValidFunctionKind(kind));
+ return kind & FunctionKind::kBaseConstructor;
+}
+
+
+inline bool IsSubclassConstructor(FunctionKind kind) {
+ DCHECK(IsValidFunctionKind(kind));
+ return kind & FunctionKind::kSubclassConstructor;
+}
+
+
+inline bool IsClassConstructor(FunctionKind kind) {
+ DCHECK(IsValidFunctionKind(kind));
+ return kind & FunctionKind::kClassConstructor;
+}
+
+
+inline bool IsConstructable(FunctionKind kind, LanguageMode mode) {
+ if (IsAccessorFunction(kind)) return false;
+ if (IsConciseMethod(kind) && !IsGeneratorFunction(kind)) return false;
+ if (IsArrowFunction(kind)) return false;
+ if (is_strong(mode)) return IsClassConstructor(kind);
+ return true;
+}
+
+
+inline bool IsInObjectLiteral(FunctionKind kind) {
+ DCHECK(IsValidFunctionKind(kind));
+ return kind & FunctionKind::kInObjectLiteral;
+}
+
+
+inline FunctionKind WithObjectLiteralBit(FunctionKind kind) {
+ kind = static_cast<FunctionKind>(kind | FunctionKind::kInObjectLiteral);
+ DCHECK(IsValidFunctionKind(kind));
+ return kind;
+}
+} // namespace internal
+} // namespace v8
namespace i = v8::internal;