diff options
Diffstat (limited to 'src/objects.h')
-rw-r--r-- | src/objects.h | 720 |
1 files changed, 649 insertions, 71 deletions
diff --git a/src/objects.h b/src/objects.h index b52bac27..c5fda7d0 100644 --- a/src/objects.h +++ b/src/objects.h @@ -585,6 +585,7 @@ struct ValueInfo : public Malloced { // A template-ized version of the IsXXX functions. template <class C> static inline bool Is(Object* obj); + class MaybeObject BASE_EMBEDDED { public: inline bool IsFailure(); @@ -606,10 +607,18 @@ class MaybeObject BASE_EMBEDDED { return reinterpret_cast<Object*>(this); } -#ifdef DEBUG +#ifdef OBJECT_PRINT // Prints this object with details. - void Print(); - void PrintLn(); + inline void Print() { + Print(stdout); + }; + inline void PrintLn() { + PrintLn(stdout); + } + void Print(FILE* out); + void PrintLn(FILE* out); +#endif +#ifdef DEBUG // Verifies the object. void Verify(); #endif @@ -654,6 +663,8 @@ class Object : public MaybeObject { inline bool IsMap(); inline bool IsFixedArray(); inline bool IsDescriptorArray(); + inline bool IsDeoptimizationInputData(); + inline bool IsDeoptimizationOutputData(); inline bool IsContext(); inline bool IsCatchContext(); inline bool IsGlobalContext(); @@ -759,7 +770,10 @@ class Object : public MaybeObject { #endif // Prints this object without details. - void ShortPrint(); + inline void ShortPrint() { + ShortPrint(stdout); + } + void ShortPrint(FILE* out); // Prints this object without details to a message accumulator. void ShortPrint(StringStream* accumulator); @@ -798,7 +812,10 @@ class Smi: public Object { static inline Smi* cast(Object* object); // Dispatched behavior. - void SmiPrint(); + inline void SmiPrint() { + SmiPrint(stdout); + } + void SmiPrint(FILE* out); void SmiPrint(StringStream* accumulator); #ifdef DEBUG void SmiVerify(); @@ -867,7 +884,10 @@ class Failure: public MaybeObject { static inline Failure* cast(MaybeObject* object); // Dispatched behavior. - void FailurePrint(); + inline void FailurePrint() { + FailurePrint(stdout); + } + void FailurePrint(FILE* out); void FailurePrint(StringStream* accumulator); #ifdef DEBUG void FailureVerify(); @@ -1096,14 +1116,23 @@ class HeapObject: public Object { // Dispatched behavior. void HeapObjectShortPrint(StringStream* accumulator); +#ifdef OBJECT_PRINT + inline void HeapObjectPrint() { + HeapObjectPrint(stdout); + } + void HeapObjectPrint(FILE* out); +#endif #ifdef DEBUG - void HeapObjectPrint(); void HeapObjectVerify(); inline void VerifyObjectField(int offset); inline void VerifySmiField(int offset); +#endif - void PrintHeader(const char* id); +#ifdef OBJECT_PRINT + void PrintHeader(FILE* out, const char* id); +#endif +#ifdef DEBUG // Verify a pointer is a valid HeapObject pointer that points to object // areas in the heap. static void VerifyHeapPointer(Object* p); @@ -1186,7 +1215,10 @@ class HeapNumber: public HeapObject { // Dispatched behavior. Object* HeapNumberToBoolean(); - void HeapNumberPrint(); + inline void HeapNumberPrint() { + HeapNumberPrint(stdout); + } + void HeapNumberPrint(FILE* out); void HeapNumberPrint(StringStream* accumulator); #ifdef DEBUG void HeapNumberVerify(); @@ -1365,7 +1397,7 @@ class JSObject: public HeapObject { MUST_USE_RESULT MaybeObject* DefineAccessor(String* name, bool is_getter, - JSFunction* fun, + Object* fun, PropertyAttributes attributes); Object* LookupAccessor(String* name, bool is_getter); @@ -1646,12 +1678,28 @@ class JSObject: public HeapObject { // Dispatched behavior. void JSObjectShortPrint(StringStream* accumulator); +#ifdef OBJECT_PRINT + inline void JSObjectPrint() { + JSObjectPrint(stdout); + } + void JSObjectPrint(FILE* out); +#endif #ifdef DEBUG - void JSObjectPrint(); void JSObjectVerify(); - void PrintProperties(); - void PrintElements(); +#endif +#ifdef OBJECT_PRINT + inline void PrintProperties() { + PrintProperties(stdout); + } + void PrintProperties(FILE* out); + + inline void PrintElements() { + PrintElements(stdout); + } + void PrintElements(FILE* out); +#endif +#ifdef DEBUG // Structure for collecting spill information about JSObjects. class SpillInformation { public: @@ -1686,7 +1734,7 @@ class JSObject: public HeapObject { static const uint32_t kMaxGap = 1024; static const int kMaxFastElementsLength = 5000; static const int kInitialMaxFastElementArray = 100000; - static const int kMaxFastProperties = 8; + static const int kMaxFastProperties = 12; 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 @@ -1832,8 +1880,13 @@ class FixedArray: public HeapObject { static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize; // Dispatched behavior. +#ifdef OBJECT_PRINT + inline void FixedArrayPrint() { + FixedArrayPrint(stdout); + } + void FixedArrayPrint(FILE* out); +#endif #ifdef DEBUG - void FixedArrayPrint(); void FixedArrayVerify(); // Checks if two FixedArrays have identical contents. bool IsEqualTo(FixedArray* other); @@ -2009,10 +2062,15 @@ class DescriptorArray: public FixedArray { static const int kEnumCacheBridgeCacheOffset = kEnumCacheBridgeEnumOffset + kPointerSize; -#ifdef DEBUG +#ifdef OBJECT_PRINT // Print all the descriptors. - void PrintDescriptors(); + inline void PrintDescriptors() { + PrintDescriptors(stdout); + } + void PrintDescriptors(FILE* out); +#endif +#ifdef DEBUG // Is the descriptor array sorted and without duplicates? bool IsSortedNoDuplicates(); @@ -2393,8 +2451,11 @@ class Dictionary: public HashTable<Shape, Key> { // Ensure enough space for n additional elements. MUST_USE_RESULT MaybeObject* EnsureCapacity(int n, Key key); -#ifdef DEBUG - void Print(); +#ifdef OBJECT_PRINT + inline void Print() { + Print(stdout); + } + void Print(FILE* out); #endif // Returns the key (slow). Object* SlowReverseLookup(Object* value); @@ -2616,8 +2677,13 @@ class ByteArray: public HeapObject { inline int ByteArraySize() { return SizeFor(this->length()); } +#ifdef OBJECT_PRINT + inline void ByteArrayPrint() { + ByteArrayPrint(stdout); + } + void ByteArrayPrint(FILE* out); +#endif #ifdef DEBUG - void ByteArrayPrint(); void ByteArrayVerify(); #endif @@ -2666,8 +2732,13 @@ class PixelArray: public HeapObject { // Casting. static inline PixelArray* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void PixelArrayPrint() { + PixelArrayPrint(stdout); + } + void PixelArrayPrint(FILE* out); +#endif #ifdef DEBUG - void PixelArrayPrint(); void PixelArrayVerify(); #endif // DEBUG @@ -2738,8 +2809,13 @@ class ExternalByteArray: public ExternalArray { // Casting. static inline ExternalByteArray* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void ExternalByteArrayPrint() { + ExternalByteArrayPrint(stdout); + } + void ExternalByteArrayPrint(FILE* out); +#endif #ifdef DEBUG - void ExternalByteArrayPrint(); void ExternalByteArrayVerify(); #endif // DEBUG @@ -2761,8 +2837,13 @@ class ExternalUnsignedByteArray: public ExternalArray { // Casting. static inline ExternalUnsignedByteArray* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void ExternalUnsignedByteArrayPrint() { + ExternalUnsignedByteArrayPrint(stdout); + } + void ExternalUnsignedByteArrayPrint(FILE* out); +#endif #ifdef DEBUG - void ExternalUnsignedByteArrayPrint(); void ExternalUnsignedByteArrayVerify(); #endif // DEBUG @@ -2784,8 +2865,13 @@ class ExternalShortArray: public ExternalArray { // Casting. static inline ExternalShortArray* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void ExternalShortArrayPrint() { + ExternalShortArrayPrint(stdout); + } + void ExternalShortArrayPrint(FILE* out); +#endif #ifdef DEBUG - void ExternalShortArrayPrint(); void ExternalShortArrayVerify(); #endif // DEBUG @@ -2807,8 +2893,13 @@ class ExternalUnsignedShortArray: public ExternalArray { // Casting. static inline ExternalUnsignedShortArray* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void ExternalUnsignedShortArrayPrint() { + ExternalUnsignedShortArrayPrint(stdout); + } + void ExternalUnsignedShortArrayPrint(FILE* out); +#endif #ifdef DEBUG - void ExternalUnsignedShortArrayPrint(); void ExternalUnsignedShortArrayVerify(); #endif // DEBUG @@ -2830,8 +2921,13 @@ class ExternalIntArray: public ExternalArray { // Casting. static inline ExternalIntArray* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void ExternalIntArrayPrint() { + ExternalIntArrayPrint(stdout); + } + void ExternalIntArrayPrint(FILE* out); +#endif #ifdef DEBUG - void ExternalIntArrayPrint(); void ExternalIntArrayVerify(); #endif // DEBUG @@ -2853,8 +2949,13 @@ class ExternalUnsignedIntArray: public ExternalArray { // Casting. static inline ExternalUnsignedIntArray* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void ExternalUnsignedIntArrayPrint() { + ExternalUnsignedIntArrayPrint(stdout); + } + void ExternalUnsignedIntArrayPrint(FILE* out); +#endif #ifdef DEBUG - void ExternalUnsignedIntArrayPrint(); void ExternalUnsignedIntArrayVerify(); #endif // DEBUG @@ -2876,8 +2977,13 @@ class ExternalFloatArray: public ExternalArray { // Casting. static inline ExternalFloatArray* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void ExternalFloatArrayPrint() { + ExternalFloatArrayPrint(stdout); + } + void ExternalFloatArrayPrint(FILE* out); +#endif #ifdef DEBUG - void ExternalFloatArrayPrint(); void ExternalFloatArrayVerify(); #endif // DEBUG @@ -2886,6 +2992,122 @@ class ExternalFloatArray: public ExternalArray { }; +// 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 +// functions were inlined then first N elements of the literal array will +// contain these functions. +// +// It can be empty. +class DeoptimizationInputData: public FixedArray { + public: + // Layout description. Indices in the array. + static const int kTranslationByteArrayIndex = 0; + static const int kInlinedFunctionCountIndex = 1; + static const int kLiteralArrayIndex = 2; + static const int kOsrAstIdIndex = 3; + static const int kOsrPcOffsetIndex = 4; + static const int kFirstDeoptEntryIndex = 5; + + // Offsets of deopt entry elements relative to the start of the entry. + static const int kAstIdOffset = 0; + static const int kTranslationIndexOffset = 1; + static const int kArgumentsStackHeightOffset = 2; + static const int kDeoptEntrySize = 3; + + // Simple element accessors. +#define DEFINE_ELEMENT_ACCESSORS(name, type) \ + type* name() { \ + return type::cast(get(k##name##Index)); \ + } \ + void Set##name(type* value) { \ + set(k##name##Index, value); \ + } + + DEFINE_ELEMENT_ACCESSORS(TranslationByteArray, ByteArray) + DEFINE_ELEMENT_ACCESSORS(InlinedFunctionCount, Smi) + DEFINE_ELEMENT_ACCESSORS(LiteralArray, FixedArray) + DEFINE_ELEMENT_ACCESSORS(OsrAstId, Smi) + DEFINE_ELEMENT_ACCESSORS(OsrPcOffset, Smi) + + // Unchecked accessor to be used during GC. + FixedArray* UncheckedLiteralArray() { + return reinterpret_cast<FixedArray*>(get(kLiteralArrayIndex)); + } + +#undef DEFINE_ELEMENT_ACCESSORS + + // Accessors for elements of the ith deoptimization entry. +#define DEFINE_ENTRY_ACCESSORS(name, type) \ + type* name(int i) { \ + return type::cast(get(IndexForEntry(i) + k##name##Offset)); \ + } \ + void Set##name(int i, type* value) { \ + set(IndexForEntry(i) + k##name##Offset, value); \ + } + + DEFINE_ENTRY_ACCESSORS(AstId, Smi) + DEFINE_ENTRY_ACCESSORS(TranslationIndex, Smi) + DEFINE_ENTRY_ACCESSORS(ArgumentsStackHeight, Smi) + +#undef DEFINE_ENTRY_ACCESSORS + + int DeoptCount() { + return (length() - kFirstDeoptEntryIndex) / kDeoptEntrySize; + } + + // Allocates a DeoptimizationInputData. + MUST_USE_RESULT static MaybeObject* Allocate(int deopt_entry_count, + PretenureFlag pretenure); + + // Casting. + static inline DeoptimizationInputData* cast(Object* obj); + +#ifdef OBJECT_PRINT + void DeoptimizationInputDataPrint(FILE* out); +#endif + + private: + static int IndexForEntry(int i) { + return kFirstDeoptEntryIndex + (i * kDeoptEntrySize); + } + + static int LengthFor(int entry_count) { + return IndexForEntry(entry_count); + } +}; + + +// DeoptimizationOutputData is a fixed array used to hold the deoptimization +// data for code generated by the full compiler. +// The format of the these objects is +// [i * 2]: Ast ID for ith deoptimization. +// [i * 2 + 1]: PC and state of ith deoptimization +class DeoptimizationOutputData: public FixedArray { + public: + int DeoptPoints() { return length() / 2; } + Smi* AstId(int index) { return Smi::cast(get(index * 2)); } + void SetAstId(int index, Smi* id) { set(index * 2, id); } + Smi* PcAndState(int index) { return Smi::cast(get(1 + index * 2)); } + void SetPcAndState(int index, Smi* offset) { set(1 + index * 2, offset); } + + static int LengthOfFixedArray(int deopt_points) { + return deopt_points * 2; + } + + // Allocates a DeoptimizationOutputData. + MUST_USE_RESULT static MaybeObject* Allocate(int number_of_deopt_points, + PretenureFlag pretenure); + + // Casting. + static inline DeoptimizationOutputData* cast(Object* obj); + +#ifdef OBJECT_PRINT + void DeoptimizationOutputDataPrint(FILE* out); +#endif +}; + + // Code describes objects with on-the-fly generated machine code. class Code: public HeapObject { public: @@ -2900,6 +3122,7 @@ class Code: public HeapObject { enum Kind { FUNCTION, + OPTIMIZED_FUNCTION, STUB, BUILTIN, LOAD_IC, @@ -2909,13 +3132,15 @@ class Code: public HeapObject { STORE_IC, KEYED_STORE_IC, BINARY_OP_IC, + TYPE_RECORDING_BINARY_OP_IC, + COMPARE_IC, // No more than 16 kinds. The value currently encoded in four bits in // Flags. // Pseudo-kinds. REGEXP = BUILTIN, FIRST_IC_KIND = LOAD_IC, - LAST_IC_KIND = BINARY_OP_IC + LAST_IC_KIND = COMPARE_IC }; enum { @@ -2927,7 +3152,10 @@ class Code: public HeapObject { static const char* Kind2String(Kind kind); static const char* ICState2String(InlineCacheState state); static const char* PropertyType2String(PropertyType type); - void Disassemble(const char* name); + inline void Disassemble(const char* name) { + Disassemble(name, stdout); + } + void Disassemble(const char* name, FILE* out); #endif // ENABLE_DISASSEMBLER // [instruction_size]: Size of the native instructions @@ -2936,9 +3164,14 @@ class Code: public HeapObject { // [relocation_info]: Code relocation information DECL_ACCESSORS(relocation_info, ByteArray) + void InvalidateRelocation(); - // Unchecked accessor to be used during GC. + // [deoptimization_data]: Array containing data for deopt. + DECL_ACCESSORS(deoptimization_data, FixedArray) + + // Unchecked accessors to be used during GC. inline ByteArray* unchecked_relocation_info(); + inline FixedArray* unchecked_deoptimization_data(); inline int relocation_size(); @@ -2961,10 +3194,77 @@ class Code: public HeapObject { 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_type_recording_binary_op_stub() { + return kind() == TYPE_RECORDING_BINARY_OP_IC; + } + inline bool is_compare_ic_stub() { return kind() == COMPARE_IC; } // [major_key]: For kind STUB or BINARY_OP_IC, the major key. inline int major_key(); - inline void set_major_key(int major); + inline void set_major_key(int value); + + // [optimizable]: For FUNCTION kind, tells if it is optimizable. + inline bool optimizable(); + inline void set_optimizable(bool value); + + // [has_deoptimization_support]: For FUNCTION kind, tells if it has + // deoptimization support. + inline bool has_deoptimization_support(); + inline void set_has_deoptimization_support(bool value); + + // [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for + // how long the function has been marked for OSR and therefore which + // level of loop nesting we are willing to do on-stack replacement + // for. + inline void set_allow_osr_at_loop_nesting_level(int level); + inline int allow_osr_at_loop_nesting_level(); + + // [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots + // reserved in the code prologue. + inline unsigned stack_slots(); + inline void set_stack_slots(unsigned slots); + + // [safepoint_table_start]: For kind OPTIMIZED_CODE, the offset in + // the instruction stream where the safepoint table starts. + inline unsigned safepoint_table_start(); + inline void set_safepoint_table_start(unsigned offset); + + // [stack_check_table_start]: For kind FUNCTION, the offset in the + // instruction stream where the stack check table starts. + inline unsigned stack_check_table_start(); + inline void set_stack_check_table_start(unsigned offset); + + // [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); + + // [binary op type]: For all BINARY_OP_IC. + inline byte binary_op_type(); + inline void set_binary_op_type(byte value); + + // [type-recording binary op type]: For all TYPE_RECORDING_BINARY_OP_IC. + inline byte type_recording_binary_op_type(); + inline void set_type_recording_binary_op_type(byte value); + inline byte type_recording_binary_op_result_type(); + inline void set_type_recording_binary_op_result_type(byte value); + + // [compare state]: For kind compare IC stubs, tells what state the + // stub is in. + inline byte compare_state(); + inline void set_compare_state(byte value); + + // Get the safepoint entry for the given pc. Returns NULL for + // non-safepoint pcs. + uint8_t* GetSafepointEntry(Address pc); + + // Mark this code object as not having a stack check table. Assumes kind + // is FUNCTION. + void SetNoStackCheckTable(); + + // Find the first map in an IC stub. + Map* FindFirstMap(); // Flags operations. static inline Flags ComputeFlags(Kind kind, @@ -3048,22 +3348,54 @@ class Code: public HeapObject { template<typename StaticVisitor> inline void CodeIterateBody(); +#ifdef OBJECT_PRINT + inline void CodePrint() { + CodePrint(stdout); + } + void CodePrint(FILE* out); +#endif #ifdef DEBUG - void CodePrint(); void CodeVerify(); #endif + + // Max loop nesting marker used to postpose OSR. We don't take loop + // nesting that is deeper than 5 levels into account. + static const int kMaxLoopNestingMarker = 6; + // Layout description. static const int kInstructionSizeOffset = HeapObject::kHeaderSize; static const int kRelocationInfoOffset = kInstructionSizeOffset + kIntSize; - static const int kFlagsOffset = kRelocationInfoOffset + kPointerSize; + static const int kDeoptimizationDataOffset = + kRelocationInfoOffset + kPointerSize; + static const int kFlagsOffset = kDeoptimizationDataOffset + kPointerSize; static const int kKindSpecificFlagsOffset = kFlagsOffset + kIntSize; + + static const int kKindSpecificFlagsSize = 2 * kIntSize; + + static const int kHeaderPaddingStart = kKindSpecificFlagsOffset + + kKindSpecificFlagsSize; + // Add padding to align the instruction start following right after // the Code object header. static const int kHeaderSize = - CODE_POINTER_ALIGN(kKindSpecificFlagsOffset + kIntSize); + (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask; // Byte offsets within kKindSpecificFlagsOffset. - static const int kStubMajorKeyOffset = kKindSpecificFlagsOffset + 1; + static const int kStubMajorKeyOffset = kKindSpecificFlagsOffset; + static const int kOptimizableOffset = kKindSpecificFlagsOffset; + static const int kStackSlotsOffset = kKindSpecificFlagsOffset; + static const int kCheckTypeOffset = kKindSpecificFlagsOffset; + + static const int kCompareStateOffset = kStubMajorKeyOffset + 1; + static const int kBinaryOpTypeOffset = kStubMajorKeyOffset + 1; + static const int kHasDeoptimizationSupportOffset = kOptimizableOffset + 1; + + static const int kBinaryOpReturnTypeOffset = kBinaryOpTypeOffset + 1; + static const int kAllowOSRAtLoopNestingLevelOffset = + kHasDeoptimizationSupportOffset + 1; + + static const int kSafepointTableStartOffset = kStackSlotsOffset + kIntSize; + static const int kStackCheckTableStartOffset = kStackSlotsOffset + kIntSize; // Flags layout. static const int kFlagsICStateShift = 0; @@ -3239,6 +3571,13 @@ class Map: public HeapObject { // [stub cache]: contains stubs compiled for this map. DECL_ACCESSORS(code_cache, Object) + // Lookup in the map's instance descriptors and fill out the result + // with the given holder if the name is found. The holder may be + // NULL when this function is used from the compiler. + void LookupInDescriptors(JSObject* holder, + String* name, + LookupResult* result); + MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode, @@ -3303,8 +3642,13 @@ class Map: public HeapObject { void ClearNonLiveTransitions(Object* real_prototype); // Dispatched behavior. +#ifdef OBJECT_PRINT + inline void MapPrint() { + MapPrint(stdout); + } + void MapPrint(FILE* out); +#endif #ifdef DEBUG - void MapPrint(); void MapVerify(); void SharedMapVerify(); #endif @@ -3460,8 +3804,13 @@ class Script: public Struct { // resource is accessible. Otherwise, always return true. inline bool HasValidSource(); +#ifdef OBJECT_PRINT + inline void ScriptPrint() { + ScriptPrint(stdout); + } + void ScriptPrint(FILE* out); +#endif #ifdef DEBUG - void ScriptPrint(); void ScriptVerify(); #endif @@ -3486,6 +3835,52 @@ class Script: public Struct { }; +// List of builtin functions we want to identify to improve code +// generation. +// +// Each entry has a name of a global object property holding an object +// optionally followed by ".prototype", a name of a builtin function +// on the object (the one the id is set for), and a label. +// +// Installation of ids for the selected builtin functions is handled +// by the bootstrapper. +// +// NOTE: Order is important: math functions should be at the end of +// the list and MathFloor should be the first math function. +#define FUNCTIONS_WITH_ID_LIST(V) \ + V(Array.prototype, push, ArrayPush) \ + V(Array.prototype, pop, ArrayPop) \ + 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) + + +enum BuiltinFunctionId { +#define DECLARE_FUNCTION_ID(ignored1, ignore2, name) \ + k##name, + FUNCTIONS_WITH_ID_LIST(DECLARE_FUNCTION_ID) +#undef DECLARE_FUNCTION_ID + // Fake id for a special case of Math.pow. Note, it continues the + // list of math functions. + kMathPowHalf, + kFirstMathFunctionId = kMathFloor +}; + + // SharedFunctionInfo describes the JSFunction information that can be // shared by multiple instances of the function. class SharedFunctionInfo: public HeapObject { @@ -3623,7 +4018,7 @@ class SharedFunctionInfo: public HeapObject { // [function data]: This field holds some additional data for function. // Currently it either has FunctionTemplateInfo to make benefit the API - // or Smi identifying a custom call generator. + // or Smi identifying a builtin function. // In the long run we don't want all functions to have this field but // we can fix that when we have a better model for storing hidden data // on objects. @@ -3631,8 +4026,9 @@ class SharedFunctionInfo: public HeapObject { inline bool IsApiFunction(); inline FunctionTemplateInfo* get_api_func_data(); - inline bool HasCustomCallGenerator(); - inline int custom_call_generator_id(); + inline bool HasBuiltinFunctionId(); + inline bool IsBuiltinMathFunction(); + inline BuiltinFunctionId builtin_function_id(); // [script info]: Script from which the function originates. DECL_ACCESSORS(script, Object) @@ -3687,6 +4083,11 @@ class SharedFunctionInfo: public HeapObject { inline int compiler_hints(); inline void set_compiler_hints(int value); + // A counter used to determine when to stress the deoptimizer with a + // deopt. + inline Smi* deopt_counter(); + inline void set_deopt_counter(Smi* counter); + // Add information on assignments of the form this.x = ...; void SetThisPropertyAssignmentsInfo( bool has_only_simple_this_property_assignments, @@ -3716,6 +4117,24 @@ class SharedFunctionInfo: public HeapObject { inline int code_age(); inline void set_code_age(int age); + // Indicates whether optimizations have been disabled for this + // shared function info. If a function is repeatedly optimized or if + // we cannot optimize the function we disable optimization to avoid + // spending time attempting to optimize it again. + inline bool optimization_disabled(); + inline void set_optimization_disabled(bool value); + + // Indicates whether or not the code in the shared function support + // deoptimization. + inline bool has_deoptimization_support(); + + // Enable deoptimization support through recompiled code. + void EnableDeoptimizationSupport(Code* recompiled); + + // Lookup the bailout ID and ASSERT that it exists in the non-optimized + // code, returns whether it asserted (i.e., always true if assertions are + // disabled). + bool VerifyBailoutId(int id); // Check whether a inlined constructor can be generated with the given // prototype. @@ -3739,6 +4158,12 @@ class SharedFunctionInfo: public HeapObject { bool HasSourceCode(); Object* GetSourceCode(); + inline int opt_count(); + inline void set_opt_count(int opt_count); + + // Source size of this function. + int SourceSize(); + // Calculate the instance size. int CalculateInstanceSize(); @@ -3748,8 +4173,13 @@ class SharedFunctionInfo: public HeapObject { // Dispatched behavior. // Set max_length to -1 for unlimited length. void SourceCodePrint(StringStream* accumulator, int max_length); +#ifdef OBJECT_PRINT + inline void SharedFunctionInfoPrint() { + SharedFunctionInfoPrint(stdout); + } + void SharedFunctionInfoPrint(FILE* out); +#endif #ifdef DEBUG - void SharedFunctionInfoPrint(); void SharedFunctionInfoVerify(); #endif @@ -3776,10 +4206,12 @@ class SharedFunctionInfo: public HeapObject { kInferredNameOffset + kPointerSize; static const int kThisPropertyAssignmentsOffset = kInitialMapOffset + kPointerSize; + static const int kDeoptCounterOffset = + kThisPropertyAssignmentsOffset + kPointerSize; #if V8_HOST_ARCH_32_BIT // Smi fields. static const int kLengthOffset = - kThisPropertyAssignmentsOffset + kPointerSize; + kDeoptCounterOffset + kPointerSize; static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize; static const int kExpectedNofPropertiesOffset = kFormalParameterCountOffset + kPointerSize; @@ -3795,8 +4227,10 @@ class SharedFunctionInfo: public HeapObject { kFunctionTokenPositionOffset + kPointerSize; static const int kThisPropertyAssignmentsCountOffset = kCompilerHintsOffset + kPointerSize; + static const int kOptCountOffset = + kThisPropertyAssignmentsCountOffset + kPointerSize; // Total size. - static const int kSize = kThisPropertyAssignmentsCountOffset + kPointerSize; + static const int kSize = kOptCountOffset + kPointerSize; #else // The only reason to use smi fields instead of int fields // is to allow iteration without maps decoding during @@ -3808,7 +4242,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 = - kThisPropertyAssignmentsOffset + kPointerSize; + kDeoptCounterOffset + kPointerSize; static const int kFormalParameterCountOffset = kLengthOffset + kIntSize; @@ -3829,9 +4263,11 @@ class SharedFunctionInfo: public HeapObject { static const int kThisPropertyAssignmentsCountOffset = kCompilerHintsOffset + kIntSize; + static const int kOptCountOffset = + kThisPropertyAssignmentsCountOffset + kIntSize; // Total size. - static const int kSize = kThisPropertyAssignmentsCountOffset + kIntSize; + static const int kSize = kOptCountOffset + kIntSize; #endif @@ -3867,7 +4303,8 @@ class SharedFunctionInfo: public HeapObject { static const int kAllowLazyCompilation = 2; static const int kLiveObjectsMayExist = 3; static const int kCodeAgeShift = 4; - static const int kCodeAgeMask = 7; + static const int kCodeAgeMask = 0x7; + static const int kOptimizationDisabled = 7; DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo); }; @@ -3895,13 +4332,34 @@ class JSFunction: public JSObject { // [[Call]] and [[Construct]] description in ECMA-262, section // 8.6.2, page 27. inline Code* code(); - inline void set_code(Code* value); + inline void set_code(Code* code); + inline void ReplaceCode(Code* code); inline Code* unchecked_code(); // Tells whether this function is builtin. inline bool IsBuiltin(); + // Tells whether or not the function needs arguments adaption. + inline bool NeedsArgumentsAdaption(); + + // Tells whether or not this function has been optimized. + inline bool IsOptimized(); + + // Mark this function for lazy recompilation. The function will be + // recompiled the next time it is executed. + void MarkForLazyRecompilation(); + + // Tells whether or not the function is already marked for lazy + // recompilation. + inline bool IsMarkedForLazyRecompilation(); + + // Compute a hash code for the source code of this function. + uint32_t SourceHash(); + + // Check whether or not this function is inlineable. + bool IsInlineable(); + // [literals]: Fixed array holding the materialized literals. // // If the function contains object, regexp or array literals, the @@ -3948,6 +4406,16 @@ class JSFunction: public JSObject { // Returns if this function has been compiled to native code yet. inline bool is_compiled(); + // [next_function_link]: Field for linking functions. This list is treated as + // a weak list by the GC. + DECL_ACCESSORS(next_function_link, Object) + + // Prints the name of the function using PrintF. + inline void PrintName() { + PrintName(stdout); + } + void PrintName(FILE* out); + // Casting. static inline JSFunction* cast(Object* obj); @@ -3956,8 +4424,13 @@ class JSFunction: public JSObject { void JSFunctionIterateBody(int object_size, ObjectVisitor* v); // Dispatched behavior. +#ifdef OBJECT_PRINT + inline void JSFunctionPrint() { + JSFunctionPrint(stdout); + } + void JSFunctionPrint(FILE* out); +#endif #ifdef DEBUG - void JSFunctionPrint(); void JSFunctionVerify(); #endif @@ -3967,7 +4440,8 @@ class JSFunction: public JSObject { // Retrieve the global context from a function's literal array. static Context* GlobalContextFromLiterals(FixedArray* literals); - // Layout descriptors. + // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to + // kSize) is weak and has special handling during garbage collection. static const int kCodeEntryOffset = JSObject::kHeaderSize; static const int kPrototypeOrInitialMapOffset = kCodeEntryOffset + kPointerSize; @@ -3975,7 +4449,9 @@ class JSFunction: public JSObject { kPrototypeOrInitialMapOffset + kPointerSize; static const int kContextOffset = kSharedFunctionInfoOffset + kPointerSize; static const int kLiteralsOffset = kContextOffset + kPointerSize; - static const int kSize = kLiteralsOffset + kPointerSize; + static const int kNonWeakFieldsEndOffset = kLiteralsOffset + kPointerSize; + static const int kNextFunctionLinkOffset = kNonWeakFieldsEndOffset; + static const int kSize = kNextFunctionLinkOffset + kPointerSize; // Layout of the literals array. static const int kLiteralsPrefixSize = 1; @@ -4003,8 +4479,13 @@ class JSGlobalProxy : public JSObject { static inline JSGlobalProxy* cast(Object* obj); // Dispatched behavior. +#ifdef OBJECT_PRINT + inline void JSGlobalProxyPrint() { + JSGlobalProxyPrint(stdout); + } + void JSGlobalProxyPrint(FILE* out); +#endif #ifdef DEBUG - void JSGlobalProxyPrint(); void JSGlobalProxyVerify(); #endif @@ -4020,6 +4501,7 @@ class JSGlobalProxy : public JSObject { // Forward declaration. class JSBuiltinsObject; +class JSGlobalPropertyCell; // Common super class for JavaScript global objects and the special // builtins global objects. @@ -4035,7 +4517,7 @@ class GlobalObject: public JSObject { DECL_ACCESSORS(global_receiver, JSObject) // Retrieve the property cell used to store a property. - Object* GetPropertyCell(LookupResult* result); + JSGlobalPropertyCell* 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 @@ -4073,8 +4555,13 @@ class JSGlobalObject: public GlobalObject { static inline JSGlobalObject* cast(Object* obj); // Dispatched behavior. +#ifdef OBJECT_PRINT + inline void JSGlobalObjectPrint() { + JSGlobalObjectPrint(stdout); + } + void JSGlobalObjectPrint(FILE* out); +#endif #ifdef DEBUG - void JSGlobalObjectPrint(); void JSGlobalObjectVerify(); #endif @@ -4102,8 +4589,13 @@ class JSBuiltinsObject: public GlobalObject { static inline JSBuiltinsObject* cast(Object* obj); // Dispatched behavior. +#ifdef OBJECT_PRINT + inline void JSBuiltinsObjectPrint() { + JSBuiltinsObjectPrint(stdout); + } + void JSBuiltinsObjectPrint(FILE* out); +#endif #ifdef DEBUG - void JSBuiltinsObjectPrint(); void JSBuiltinsObjectVerify(); #endif @@ -4140,8 +4632,13 @@ class JSValue: public JSObject { static inline JSValue* cast(Object* obj); // Dispatched behavior. +#ifdef OBJECT_PRINT + inline void JSValuePrint() { + JSValuePrint(stdout); + } + void JSValuePrint(FILE* out); +#endif #ifdef DEBUG - void JSValuePrint(); void JSValueVerify(); #endif @@ -4297,6 +4794,9 @@ class CompilationCacheTable: public HashTable<CompilationCacheShape, MaybeObject* PutEval(String* src, Context* context, Object* value); MaybeObject* PutRegExp(String* src, JSRegExp::Flags flags, FixedArray* value); + // Remove given value from cache. + void Remove(Object* value); + static inline CompilationCacheTable* cast(Object* obj); private: @@ -4327,8 +4827,13 @@ class CodeCache: public Struct { static inline CodeCache* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void CodeCachePrint() { + CodeCachePrint(stdout); + } + void CodeCachePrint(FILE* out); +#endif #ifdef DEBUG - void CodeCachePrint(); void CodeCacheVerify(); #endif @@ -4629,8 +5134,13 @@ class String: public HeapObject { // Dispatched behavior. void StringShortPrint(StringStream* accumulator); +#ifdef OBJECT_PRINT + inline void StringPrint() { + StringPrint(stdout); + } + void StringPrint(FILE* out); +#endif #ifdef DEBUG - void StringPrint(); void StringVerify(); #endif inline bool IsFlat(); @@ -5185,7 +5695,12 @@ class JSGlobalPropertyCell: public HeapObject { #ifdef DEBUG void JSGlobalPropertyCellVerify(); - void JSGlobalPropertyCellPrint(); +#endif +#ifdef OBJECT_PRINT + inline void JSGlobalPropertyCellPrint() { + JSGlobalPropertyCellPrint(stdout); + } + void JSGlobalPropertyCellPrint(FILE* out); #endif // Layout description. @@ -5220,8 +5735,13 @@ class Proxy: public HeapObject { template<typename StaticVisitor> inline void ProxyIterateBody(); +#ifdef OBJECT_PRINT + inline void ProxyPrint() { + ProxyPrint(stdout); + } + void ProxyPrint(FILE* out); +#endif #ifdef DEBUG - void ProxyPrint(); void ProxyVerify(); #endif @@ -5270,8 +5790,13 @@ class JSArray: public JSObject { inline void EnsureSize(int minimum_size_of_backing_fixed_array); // Dispatched behavior. +#ifdef OBJECT_PRINT + inline void JSArrayPrint() { + JSArrayPrint(stdout); + } + void JSArrayPrint(FILE* out); +#endif #ifdef DEBUG - void JSArrayPrint(); void JSArrayVerify(); #endif @@ -5342,8 +5867,13 @@ class AccessorInfo: public Struct { static inline AccessorInfo* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void AccessorInfoPrint() { + AccessorInfoPrint(stdout); + } + void AccessorInfoPrint(FILE* out); +#endif #ifdef DEBUG - void AccessorInfoPrint(); void AccessorInfoVerify(); #endif @@ -5373,8 +5903,13 @@ class AccessCheckInfo: public Struct { static inline AccessCheckInfo* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void AccessCheckInfoPrint() { + AccessCheckInfoPrint(stdout); + } + void AccessCheckInfoPrint(FILE* out); +#endif #ifdef DEBUG - void AccessCheckInfoPrint(); void AccessCheckInfoVerify(); #endif @@ -5399,8 +5934,13 @@ class InterceptorInfo: public Struct { static inline InterceptorInfo* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void InterceptorInfoPrint() { + InterceptorInfoPrint(stdout); + } + void InterceptorInfoPrint(FILE* out); +#endif #ifdef DEBUG - void InterceptorInfoPrint(); void InterceptorInfoVerify(); #endif @@ -5424,8 +5964,13 @@ class CallHandlerInfo: public Struct { static inline CallHandlerInfo* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void CallHandlerInfoPrint() { + CallHandlerInfoPrint(stdout); + } + void CallHandlerInfoPrint(FILE* out); +#endif #ifdef DEBUG - void CallHandlerInfoPrint(); void CallHandlerInfoVerify(); #endif @@ -5481,8 +6026,13 @@ class FunctionTemplateInfo: public TemplateInfo { static inline FunctionTemplateInfo* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void FunctionTemplateInfoPrint() { + FunctionTemplateInfoPrint(stdout); + } + void FunctionTemplateInfoPrint(FILE* out); +#endif #ifdef DEBUG - void FunctionTemplateInfoPrint(); void FunctionTemplateInfoVerify(); #endif @@ -5524,8 +6074,13 @@ class ObjectTemplateInfo: public TemplateInfo { static inline ObjectTemplateInfo* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void ObjectTemplateInfoPrint() { + ObjectTemplateInfoPrint(stdout); + } + void ObjectTemplateInfoPrint(FILE* out); +#endif #ifdef DEBUG - void ObjectTemplateInfoPrint(); void ObjectTemplateInfoVerify(); #endif @@ -5543,8 +6098,13 @@ class SignatureInfo: public Struct { static inline SignatureInfo* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void SignatureInfoPrint() { + SignatureInfoPrint(stdout); + } + void SignatureInfoPrint(FILE* out); +#endif #ifdef DEBUG - void SignatureInfoPrint(); void SignatureInfoVerify(); #endif @@ -5563,8 +6123,13 @@ class TypeSwitchInfo: public Struct { static inline TypeSwitchInfo* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void TypeSwitchInfoPrint() { + TypeSwitchInfoPrint(stdout); + } + void TypeSwitchInfoPrint(FILE* out); +#endif #ifdef DEBUG - void TypeSwitchInfoPrint(); void TypeSwitchInfoVerify(); #endif @@ -5610,8 +6175,13 @@ class DebugInfo: public Struct { static inline DebugInfo* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void DebugInfoPrint() { + DebugInfoPrint(stdout); + } + void DebugInfoPrint(FILE* out); +#endif #ifdef DEBUG - void DebugInfoPrint(); void DebugInfoVerify(); #endif @@ -5663,8 +6233,13 @@ class BreakPointInfo: public Struct { static inline BreakPointInfo* cast(Object* obj); +#ifdef OBJECT_PRINT + inline void BreakPointInfoPrint() { + BreakPointInfoPrint(stdout); + } + void BreakPointInfoPrint(FILE* out); +#endif #ifdef DEBUG - void BreakPointInfoPrint(); void BreakPointInfoVerify(); #endif @@ -5705,6 +6280,9 @@ class ObjectVisitor BASE_EMBEDDED { // Visits a code entry in a JS function. virtual void VisitCodeEntry(Address entry_address); + // Visits a global property cell reference in the instruction stream. + virtual void VisitGlobalPropertyCell(RelocInfo* rinfo); + // Visits a runtime entry in the instruction stream. virtual void VisitRuntimeEntry(RelocInfo* rinfo) {} |