| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE, | 172 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE, |
| 173 STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT, | 173 STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT, |
| 174 STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT, | 174 STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT, |
| 175 STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE, | 175 STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE, |
| 176 STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT, | 176 STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT, |
| 177 STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS, | 177 STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS, |
| 178 STORE_NO_TRANSITION_HANDLE_COW | 178 STORE_NO_TRANSITION_HANDLE_COW |
| 179 }; | 179 }; |
| 180 | 180 |
| 181 | 181 |
| 182 enum ContextualMode { |
| 183 NOT_CONTEXTUAL, |
| 184 CONTEXTUAL |
| 185 }; |
| 186 |
| 187 |
| 182 static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION - | 188 static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION - |
| 183 STANDARD_STORE; | 189 STANDARD_STORE; |
| 184 STATIC_ASSERT(STANDARD_STORE == 0); | 190 STATIC_ASSERT(STANDARD_STORE == 0); |
| 185 STATIC_ASSERT(kGrowICDelta == | 191 STATIC_ASSERT(kGrowICDelta == |
| 186 STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT - | 192 STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT - |
| 187 STORE_TRANSITION_SMI_TO_OBJECT); | 193 STORE_TRANSITION_SMI_TO_OBJECT); |
| 188 STATIC_ASSERT(kGrowICDelta == | 194 STATIC_ASSERT(kGrowICDelta == |
| 189 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE - | 195 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE - |
| 190 STORE_TRANSITION_SMI_TO_DOUBLE); | 196 STORE_TRANSITION_SMI_TO_DOUBLE); |
| 191 STATIC_ASSERT(kGrowICDelta == | 197 STATIC_ASSERT(kGrowICDelta == |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 // that piggy-back on marking can use the parity to ensure that they only | 296 // that piggy-back on marking can use the parity to ensure that they only |
| 291 // perform an operation on an object once per marking phase: they record the | 297 // perform an operation on an object once per marking phase: they record the |
| 292 // MarkingParity when they visit an object, and only re-visit the object when it | 298 // MarkingParity when they visit an object, and only re-visit the object when it |
| 293 // is marked again and the MarkingParity changes. | 299 // is marked again and the MarkingParity changes. |
| 294 enum MarkingParity { | 300 enum MarkingParity { |
| 295 NO_MARKING_PARITY, | 301 NO_MARKING_PARITY, |
| 296 ODD_MARKING_PARITY, | 302 ODD_MARKING_PARITY, |
| 297 EVEN_MARKING_PARITY | 303 EVEN_MARKING_PARITY |
| 298 }; | 304 }; |
| 299 | 305 |
| 306 // ICs store extra state in a Code object. The default extra state is |
| 307 // kNoExtraICState. |
| 308 typedef int ExtraICState; |
| 309 static const ExtraICState kNoExtraICState = 0; |
| 310 |
| 300 // Instance size sentinel for objects of variable size. | 311 // Instance size sentinel for objects of variable size. |
| 301 const int kVariableSizeSentinel = 0; | 312 const int kVariableSizeSentinel = 0; |
| 302 | 313 |
| 303 const int kStubMajorKeyBits = 6; | 314 const int kStubMajorKeyBits = 7; |
| 304 const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits; | 315 const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits; |
| 305 | 316 |
| 306 // All Maps have a field instance_type containing a InstanceType. | 317 // All Maps have a field instance_type containing a InstanceType. |
| 307 // It describes the type of the instances. | 318 // It describes the type of the instances. |
| 308 // | 319 // |
| 309 // As an example, a JavaScript object is a heap object and its map | 320 // As an example, a JavaScript object is a heap object and its map |
| 310 // instance_type is JS_OBJECT_TYPE. | 321 // instance_type is JS_OBJECT_TYPE. |
| 311 // | 322 // |
| 312 // The names of the string instance types are intended to systematically | 323 // The names of the string instance types are intended to systematically |
| 313 // mirror their encoding in the instance_type field of the map. The default | 324 // mirror their encoding in the instance_type field of the map. The default |
| (...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 inline void set_##name(bool value); \ | 865 inline void set_##name(bool value); \ |
| 855 | 866 |
| 856 | 867 |
| 857 #define DECL_ACCESSORS(name, type) \ | 868 #define DECL_ACCESSORS(name, type) \ |
| 858 inline type* name(); \ | 869 inline type* name(); \ |
| 859 inline void set_##name(type* value, \ | 870 inline void set_##name(type* value, \ |
| 860 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \ | 871 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \ |
| 861 | 872 |
| 862 class AccessorPair; | 873 class AccessorPair; |
| 863 class AllocationSite; | 874 class AllocationSite; |
| 864 class AllocationSiteContext; | 875 class AllocationSiteCreationContext; |
| 876 class AllocationSiteUsageContext; |
| 865 class DictionaryElementsAccessor; | 877 class DictionaryElementsAccessor; |
| 866 class ElementsAccessor; | 878 class ElementsAccessor; |
| 867 class Failure; | 879 class Failure; |
| 868 class FixedArrayBase; | 880 class FixedArrayBase; |
| 869 class ObjectVisitor; | 881 class ObjectVisitor; |
| 870 class StringStream; | 882 class StringStream; |
| 871 class Type; | 883 class Type; |
| 872 | 884 |
| 873 | 885 |
| 874 // A template-ized version of the IsXXX functions. | 886 // A template-ized version of the IsXXX functions. |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1352 inline bool IsExternal(); | 1364 inline bool IsExternal(); |
| 1353 inline bool IsAccessorInfo(); | 1365 inline bool IsAccessorInfo(); |
| 1354 | 1366 |
| 1355 inline bool IsStruct(); | 1367 inline bool IsStruct(); |
| 1356 #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) inline bool Is##Name(); | 1368 #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) inline bool Is##Name(); |
| 1357 STRUCT_LIST(DECLARE_STRUCT_PREDICATE) | 1369 STRUCT_LIST(DECLARE_STRUCT_PREDICATE) |
| 1358 #undef DECLARE_STRUCT_PREDICATE | 1370 #undef DECLARE_STRUCT_PREDICATE |
| 1359 | 1371 |
| 1360 INLINE(bool IsSpecObject()); | 1372 INLINE(bool IsSpecObject()); |
| 1361 INLINE(bool IsSpecFunction()); | 1373 INLINE(bool IsSpecFunction()); |
| 1374 bool IsCallable(); |
| 1362 | 1375 |
| 1363 // Oddball testing. | 1376 // Oddball testing. |
| 1364 INLINE(bool IsUndefined()); | 1377 INLINE(bool IsUndefined()); |
| 1365 INLINE(bool IsNull()); | 1378 INLINE(bool IsNull()); |
| 1366 INLINE(bool IsTheHole()); // Shadows MaybeObject's implementation. | 1379 INLINE(bool IsTheHole()); // Shadows MaybeObject's implementation. |
| 1367 INLINE(bool IsUninitialized()); | 1380 INLINE(bool IsUninitialized()); |
| 1368 INLINE(bool IsTrue()); | 1381 INLINE(bool IsTrue()); |
| 1369 INLINE(bool IsFalse()); | 1382 INLINE(bool IsFalse()); |
| 1370 inline bool IsArgumentsMarker(); | 1383 inline bool IsArgumentsMarker(); |
| 1371 inline bool NonFailureIsHeapObject(); | 1384 inline bool NonFailureIsHeapObject(); |
| (...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2514 // Disalow further properties to be added to the object. | 2527 // Disalow further properties to be added to the object. |
| 2515 static Handle<Object> PreventExtensions(Handle<JSObject> object); | 2528 static Handle<Object> PreventExtensions(Handle<JSObject> object); |
| 2516 | 2529 |
| 2517 // ES5 Object.freeze | 2530 // ES5 Object.freeze |
| 2518 static Handle<Object> Freeze(Handle<JSObject> object); | 2531 static Handle<Object> Freeze(Handle<JSObject> object); |
| 2519 | 2532 |
| 2520 // Called the first time an object is observed with ES7 Object.observe. | 2533 // Called the first time an object is observed with ES7 Object.observe. |
| 2521 static void SetObserved(Handle<JSObject> object); | 2534 static void SetObserved(Handle<JSObject> object); |
| 2522 | 2535 |
| 2523 // Copy object. | 2536 // Copy object. |
| 2524 static Handle<JSObject> Copy(Handle<JSObject> object, | 2537 enum DeepCopyHints { |
| 2525 Handle<AllocationSite> site); | 2538 kNoHints = 0, |
| 2539 kObjectIsShallowArray = 1 |
| 2540 }; |
| 2541 |
| 2526 static Handle<JSObject> Copy(Handle<JSObject> object); | 2542 static Handle<JSObject> Copy(Handle<JSObject> object); |
| 2527 static Handle<JSObject> DeepCopy(Handle<JSObject> object, | 2543 static Handle<JSObject> DeepCopy(Handle<JSObject> object, |
| 2528 AllocationSiteContext* site_context); | 2544 AllocationSiteUsageContext* site_context, |
| 2545 DeepCopyHints hints = kNoHints); |
| 2529 static Handle<JSObject> DeepWalk(Handle<JSObject> object, | 2546 static Handle<JSObject> DeepWalk(Handle<JSObject> object, |
| 2530 AllocationSiteContext* site_context); | 2547 AllocationSiteCreationContext* site_context); |
| 2531 | 2548 |
| 2532 // Casting. | 2549 // Casting. |
| 2533 static inline JSObject* cast(Object* obj); | 2550 static inline JSObject* cast(Object* obj); |
| 2534 | 2551 |
| 2535 // Dispatched behavior. | 2552 // Dispatched behavior. |
| 2536 void JSObjectShortPrint(StringStream* accumulator); | 2553 void JSObjectShortPrint(StringStream* accumulator); |
| 2537 DECLARE_PRINTER(JSObject) | 2554 DECLARE_PRINTER(JSObject) |
| 2538 DECLARE_VERIFIER(JSObject) | 2555 DECLARE_VERIFIER(JSObject) |
| 2539 #ifdef OBJECT_PRINT | 2556 #ifdef OBJECT_PRINT |
| 2540 void PrintProperties(FILE* out = stdout); | 2557 void PrintProperties(FILE* out = stdout); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2627 public: | 2644 public: |
| 2628 static inline int SizeOf(Map* map, HeapObject* object); | 2645 static inline int SizeOf(Map* map, HeapObject* object); |
| 2629 }; | 2646 }; |
| 2630 | 2647 |
| 2631 // Enqueue change record for Object.observe. May cause GC. | 2648 // Enqueue change record for Object.observe. May cause GC. |
| 2632 static void EnqueueChangeRecord(Handle<JSObject> object, | 2649 static void EnqueueChangeRecord(Handle<JSObject> object, |
| 2633 const char* type, | 2650 const char* type, |
| 2634 Handle<Name> name, | 2651 Handle<Name> name, |
| 2635 Handle<Object> old_value); | 2652 Handle<Object> old_value); |
| 2636 | 2653 |
| 2637 // Deliver change records to observers. May cause GC. | |
| 2638 static void DeliverChangeRecords(Isolate* isolate); | |
| 2639 | |
| 2640 private: | 2654 private: |
| 2641 friend class DictionaryElementsAccessor; | 2655 friend class DictionaryElementsAccessor; |
| 2642 friend class JSReceiver; | 2656 friend class JSReceiver; |
| 2643 friend class Object; | 2657 friend class Object; |
| 2644 | 2658 |
| 2645 static void UpdateAllocationSite(Handle<JSObject> object, | 2659 static void UpdateAllocationSite(Handle<JSObject> object, |
| 2646 ElementsKind to_kind); | 2660 ElementsKind to_kind); |
| 2647 MUST_USE_RESULT MaybeObject* UpdateAllocationSite(ElementsKind to_kind); | 2661 MUST_USE_RESULT MaybeObject* UpdateAllocationSite(ElementsKind to_kind); |
| 2648 | 2662 |
| 2649 // Used from Object::GetProperty(). | 2663 // Used from Object::GetProperty(). |
| (...skipping 2376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5026 STATIC_ASSERT(NUMBER_OF_KINDS <= 16); | 5040 STATIC_ASSERT(NUMBER_OF_KINDS <= 16); |
| 5027 | 5041 |
| 5028 static const char* Kind2String(Kind kind); | 5042 static const char* Kind2String(Kind kind); |
| 5029 | 5043 |
| 5030 // Types of stubs. | 5044 // Types of stubs. |
| 5031 enum StubType { | 5045 enum StubType { |
| 5032 NORMAL, | 5046 NORMAL, |
| 5033 FAST | 5047 FAST |
| 5034 }; | 5048 }; |
| 5035 | 5049 |
| 5036 typedef int ExtraICState; | |
| 5037 | |
| 5038 static const ExtraICState kNoExtraICState = 0; | |
| 5039 | |
| 5040 static const int kPrologueOffsetNotSet = -1; | 5050 static const int kPrologueOffsetNotSet = -1; |
| 5041 | 5051 |
| 5042 #ifdef ENABLE_DISASSEMBLER | 5052 #ifdef ENABLE_DISASSEMBLER |
| 5043 // Printing | 5053 // Printing |
| 5044 static const char* ICState2String(InlineCacheState state); | 5054 static const char* ICState2String(InlineCacheState state); |
| 5045 static const char* StubType2String(StubType type); | 5055 static const char* StubType2String(StubType type); |
| 5046 static void PrintExtraICState(FILE* out, Kind kind, ExtraICState extra); | 5056 static void PrintExtraICState(FILE* out, Kind kind, ExtraICState extra); |
| 5047 void Disassemble(const char* name, FILE* out = stdout); | 5057 void Disassemble(const char* name, FILE* out = stdout); |
| 5048 #endif // ENABLE_DISASSEMBLER | 5058 #endif // ENABLE_DISASSEMBLER |
| 5049 | 5059 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5142 // [major_key]: For kind STUB or BINARY_OP_IC, the major key. | 5152 // [major_key]: For kind STUB or BINARY_OP_IC, the major key. |
| 5143 inline int major_key(); | 5153 inline int major_key(); |
| 5144 inline void set_major_key(int value); | 5154 inline void set_major_key(int value); |
| 5145 inline bool has_major_key(); | 5155 inline bool has_major_key(); |
| 5146 | 5156 |
| 5147 // For kind STUB or ICs, tells whether or not a code object was generated by | 5157 // For kind STUB or ICs, tells whether or not a code object was generated by |
| 5148 // the optimizing compiler (but it may not be an optimized function). | 5158 // the optimizing compiler (but it may not be an optimized function). |
| 5149 bool is_crankshafted(); | 5159 bool is_crankshafted(); |
| 5150 inline void set_is_crankshafted(bool value); | 5160 inline void set_is_crankshafted(bool value); |
| 5151 | 5161 |
| 5152 // For stubs, tells whether they should always exist, so that they can be | |
| 5153 // called from other stubs. | |
| 5154 inline bool is_pregenerated(); | |
| 5155 inline void set_is_pregenerated(bool value); | |
| 5156 | |
| 5157 // [optimizable]: For FUNCTION kind, tells if it is optimizable. | 5162 // [optimizable]: For FUNCTION kind, tells if it is optimizable. |
| 5158 inline bool optimizable(); | 5163 inline bool optimizable(); |
| 5159 inline void set_optimizable(bool value); | 5164 inline void set_optimizable(bool value); |
| 5160 | 5165 |
| 5161 // [has_deoptimization_support]: For FUNCTION kind, tells if it has | 5166 // [has_deoptimization_support]: For FUNCTION kind, tells if it has |
| 5162 // deoptimization support. | 5167 // deoptimization support. |
| 5163 inline bool has_deoptimization_support(); | 5168 inline bool has_deoptimization_support(); |
| 5164 inline void set_has_deoptimization_support(bool value); | 5169 inline void set_has_deoptimization_support(bool value); |
| 5165 | 5170 |
| 5166 // [has_debug_break_slots]: For FUNCTION kind, tells if it has | 5171 // [has_debug_break_slots]: For FUNCTION kind, tells if it has |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5249 | 5254 |
| 5250 // The entire code object including its header is copied verbatim to the | 5255 // The entire code object including its header is copied verbatim to the |
| 5251 // snapshot so that it can be written in one, fast, memcpy during | 5256 // snapshot so that it can be written in one, fast, memcpy during |
| 5252 // deserialization. The deserializer will overwrite some pointers, rather | 5257 // deserialization. The deserializer will overwrite some pointers, rather |
| 5253 // like a runtime linker, but the random allocation addresses used in the | 5258 // like a runtime linker, but the random allocation addresses used in the |
| 5254 // mksnapshot process would still be present in the unlinked snapshot data, | 5259 // mksnapshot process would still be present in the unlinked snapshot data, |
| 5255 // which would make snapshot production non-reproducible. This method wipes | 5260 // which would make snapshot production non-reproducible. This method wipes |
| 5256 // out the to-be-overwritten header data for reproducible snapshots. | 5261 // out the to-be-overwritten header data for reproducible snapshots. |
| 5257 inline void WipeOutHeader(); | 5262 inline void WipeOutHeader(); |
| 5258 | 5263 |
| 5259 class ExtraICStateStrictMode: public BitField<StrictModeFlag, 0, 1> {}; | |
| 5260 class ExtraICStateKeyedAccessStoreMode: | |
| 5261 public BitField<KeyedAccessStoreMode, 1, 4> {}; // NOLINT | |
| 5262 | |
| 5263 static inline StrictModeFlag GetStrictMode(ExtraICState extra_ic_state) { | |
| 5264 return ExtraICStateStrictMode::decode(extra_ic_state); | |
| 5265 } | |
| 5266 | |
| 5267 static inline KeyedAccessStoreMode GetKeyedAccessStoreMode( | |
| 5268 ExtraICState extra_ic_state) { | |
| 5269 return ExtraICStateKeyedAccessStoreMode::decode(extra_ic_state); | |
| 5270 } | |
| 5271 | |
| 5272 static inline ExtraICState ComputeExtraICState( | |
| 5273 KeyedAccessStoreMode store_mode, | |
| 5274 StrictModeFlag strict_mode) { | |
| 5275 return ExtraICStateKeyedAccessStoreMode::encode(store_mode) | | |
| 5276 ExtraICStateStrictMode::encode(strict_mode); | |
| 5277 } | |
| 5278 | |
| 5279 // Flags operations. | 5264 // Flags operations. |
| 5280 static inline Flags ComputeFlags( | 5265 static inline Flags ComputeFlags( |
| 5281 Kind kind, | 5266 Kind kind, |
| 5282 InlineCacheState ic_state = UNINITIALIZED, | 5267 InlineCacheState ic_state = UNINITIALIZED, |
| 5283 ExtraICState extra_ic_state = kNoExtraICState, | 5268 ExtraICState extra_ic_state = kNoExtraICState, |
| 5284 StubType type = NORMAL, | 5269 StubType type = NORMAL, |
| 5285 int argc = -1, | 5270 int argc = -1, |
| 5286 InlineCacheHolderFlag holder = OWN_MAP); | 5271 InlineCacheHolderFlag holder = OWN_MAP); |
| 5287 | 5272 |
| 5288 static inline Flags ComputeMonomorphicFlags( | 5273 static inline Flags ComputeMonomorphicFlags( |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5452 public BitField<bool, 0, 1> {}; // NOLINT | 5437 public BitField<bool, 0, 1> {}; // NOLINT |
| 5453 class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {}; | 5438 class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {}; |
| 5454 class FullCodeFlagsIsCompiledOptimizable: public BitField<bool, 2, 1> {}; | 5439 class FullCodeFlagsIsCompiledOptimizable: public BitField<bool, 2, 1> {}; |
| 5455 | 5440 |
| 5456 static const int kAllowOSRAtLoopNestingLevelOffset = kFullCodeFlags + 1; | 5441 static const int kAllowOSRAtLoopNestingLevelOffset = kFullCodeFlags + 1; |
| 5457 static const int kProfilerTicksOffset = kAllowOSRAtLoopNestingLevelOffset + 1; | 5442 static const int kProfilerTicksOffset = kAllowOSRAtLoopNestingLevelOffset + 1; |
| 5458 | 5443 |
| 5459 // Flags layout. BitField<type, shift, size>. | 5444 // Flags layout. BitField<type, shift, size>. |
| 5460 class ICStateField: public BitField<InlineCacheState, 0, 3> {}; | 5445 class ICStateField: public BitField<InlineCacheState, 0, 3> {}; |
| 5461 class TypeField: public BitField<StubType, 3, 1> {}; | 5446 class TypeField: public BitField<StubType, 3, 1> {}; |
| 5462 class CacheHolderField: public BitField<InlineCacheHolderFlag, 6, 1> {}; | 5447 class CacheHolderField: public BitField<InlineCacheHolderFlag, 5, 1> {}; |
| 5463 class KindField: public BitField<Kind, 7, 4> {}; | 5448 class KindField: public BitField<Kind, 6, 4> {}; |
| 5464 class IsPregeneratedField: public BitField<bool, 11, 1> {}; | 5449 // TODO(bmeurer): Bit 10 is available for free use. :-) |
| 5465 class ExtraICStateField: public BitField<ExtraICState, 12, 5> {}; | 5450 class ExtraICStateField: public BitField<ExtraICState, 11, 6> {}; |
| 5466 class ExtendedExtraICStateField: public BitField<ExtraICState, 12, | 5451 class ExtendedExtraICStateField: public BitField<ExtraICState, 11, |
| 5467 PlatformSmiTagging::kSmiValueSize - 12 + 1> {}; // NOLINT | 5452 PlatformSmiTagging::kSmiValueSize - 11 + 1> {}; // NOLINT |
| 5468 STATIC_ASSERT(ExtraICStateField::kShift == ExtendedExtraICStateField::kShift); | 5453 STATIC_ASSERT(ExtraICStateField::kShift == ExtendedExtraICStateField::kShift); |
| 5469 | 5454 |
| 5470 // KindSpecificFlags1 layout (STUB and OPTIMIZED_FUNCTION) | 5455 // KindSpecificFlags1 layout (STUB and OPTIMIZED_FUNCTION) |
| 5471 static const int kStackSlotsFirstBit = 0; | 5456 static const int kStackSlotsFirstBit = 0; |
| 5472 static const int kStackSlotsBitCount = 24; | 5457 static const int kStackSlotsBitCount = 24; |
| 5473 static const int kHasFunctionCacheFirstBit = | 5458 static const int kHasFunctionCacheFirstBit = |
| 5474 kStackSlotsFirstBit + kStackSlotsBitCount; | 5459 kStackSlotsFirstBit + kStackSlotsBitCount; |
| 5475 static const int kHasFunctionCacheBitCount = 1; | 5460 static const int kHasFunctionCacheBitCount = 1; |
| 5476 static const int kMarkedForDeoptimizationFirstBit = | 5461 static const int kMarkedForDeoptimizationFirstBit = |
| 5477 kStackSlotsFirstBit + kStackSlotsBitCount + 1; | 5462 kStackSlotsFirstBit + kStackSlotsBitCount + 1; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 5492 | 5477 |
| 5493 // KindSpecificFlags2 layout (ALL) | 5478 // KindSpecificFlags2 layout (ALL) |
| 5494 static const int kIsCrankshaftedBit = 0; | 5479 static const int kIsCrankshaftedBit = 0; |
| 5495 class IsCrankshaftedField: public BitField<bool, | 5480 class IsCrankshaftedField: public BitField<bool, |
| 5496 kIsCrankshaftedBit, 1> {}; // NOLINT | 5481 kIsCrankshaftedBit, 1> {}; // NOLINT |
| 5497 | 5482 |
| 5498 // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION) | 5483 // KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION) |
| 5499 static const int kStubMajorKeyFirstBit = kIsCrankshaftedBit + 1; | 5484 static const int kStubMajorKeyFirstBit = kIsCrankshaftedBit + 1; |
| 5500 static const int kSafepointTableOffsetFirstBit = | 5485 static const int kSafepointTableOffsetFirstBit = |
| 5501 kStubMajorKeyFirstBit + kStubMajorKeyBits; | 5486 kStubMajorKeyFirstBit + kStubMajorKeyBits; |
| 5502 static const int kSafepointTableOffsetBitCount = 25; | 5487 static const int kSafepointTableOffsetBitCount = 24; |
| 5503 | 5488 |
| 5504 STATIC_ASSERT(kStubMajorKeyFirstBit + kStubMajorKeyBits <= 32); | 5489 STATIC_ASSERT(kStubMajorKeyFirstBit + kStubMajorKeyBits <= 32); |
| 5505 STATIC_ASSERT(kSafepointTableOffsetFirstBit + | 5490 STATIC_ASSERT(kSafepointTableOffsetFirstBit + |
| 5506 kSafepointTableOffsetBitCount <= 32); | 5491 kSafepointTableOffsetBitCount <= 32); |
| 5507 STATIC_ASSERT(1 + kStubMajorKeyBits + | 5492 STATIC_ASSERT(1 + kStubMajorKeyBits + |
| 5508 kSafepointTableOffsetBitCount <= 32); | 5493 kSafepointTableOffsetBitCount <= 32); |
| 5509 | 5494 |
| 5510 class SafepointTableOffsetField: public BitField<int, | 5495 class SafepointTableOffsetField: public BitField<int, |
| 5511 kSafepointTableOffsetFirstBit, | 5496 kSafepointTableOffsetFirstBit, |
| 5512 kSafepointTableOffsetBitCount> {}; // NOLINT | 5497 kSafepointTableOffsetBitCount> {}; // NOLINT |
| (...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6191 | 6176 |
| 6192 bool CanTransition() { | 6177 bool CanTransition() { |
| 6193 // Only JSObject and subtypes have map transitions and back pointers. | 6178 // Only JSObject and subtypes have map transitions and back pointers. |
| 6194 STATIC_ASSERT(LAST_TYPE == LAST_JS_OBJECT_TYPE); | 6179 STATIC_ASSERT(LAST_TYPE == LAST_JS_OBJECT_TYPE); |
| 6195 return instance_type() >= FIRST_JS_OBJECT_TYPE; | 6180 return instance_type() >= FIRST_JS_OBJECT_TYPE; |
| 6196 } | 6181 } |
| 6197 | 6182 |
| 6198 bool IsJSObjectMap() { | 6183 bool IsJSObjectMap() { |
| 6199 return instance_type() >= FIRST_JS_OBJECT_TYPE; | 6184 return instance_type() >= FIRST_JS_OBJECT_TYPE; |
| 6200 } | 6185 } |
| 6186 bool IsJSGlobalProxyMap() { |
| 6187 return instance_type() == JS_GLOBAL_PROXY_TYPE; |
| 6188 } |
| 6189 bool IsJSGlobalObjectMap() { |
| 6190 return instance_type() == JS_GLOBAL_OBJECT_TYPE; |
| 6191 } |
| 6192 bool IsGlobalObjectMap() { |
| 6193 const InstanceType type = instance_type(); |
| 6194 return type == JS_GLOBAL_OBJECT_TYPE || type == JS_BUILTINS_OBJECT_TYPE; |
| 6195 } |
| 6201 | 6196 |
| 6202 // Fires when the layout of an object with a leaf map changes. | 6197 // Fires when the layout of an object with a leaf map changes. |
| 6203 // This includes adding transitions to the leaf map or changing | 6198 // This includes adding transitions to the leaf map or changing |
| 6204 // the descriptor array. | 6199 // the descriptor array. |
| 6205 inline void NotifyLeafMapLayoutChange(); | 6200 inline void NotifyLeafMapLayoutChange(); |
| 6206 | 6201 |
| 6207 inline bool CanOmitMapChecks(); | 6202 inline bool CanOmitMapChecks(); |
| 6208 | 6203 |
| 6209 void AddDependentCompilationInfo(DependentCode::DependencyGroup group, | 6204 void AddDependentCompilationInfo(DependentCode::DependencyGroup group, |
| 6210 CompilationInfo* info); | 6205 CompilationInfo* info); |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6492 V(Array.prototype, pop, ArrayPop) \ | 6487 V(Array.prototype, pop, ArrayPop) \ |
| 6493 V(Function.prototype, apply, FunctionApply) \ | 6488 V(Function.prototype, apply, FunctionApply) \ |
| 6494 V(String.prototype, charCodeAt, StringCharCodeAt) \ | 6489 V(String.prototype, charCodeAt, StringCharCodeAt) \ |
| 6495 V(String.prototype, charAt, StringCharAt) \ | 6490 V(String.prototype, charAt, StringCharAt) \ |
| 6496 V(String, fromCharCode, StringFromCharCode) \ | 6491 V(String, fromCharCode, StringFromCharCode) \ |
| 6497 V(Math, floor, MathFloor) \ | 6492 V(Math, floor, MathFloor) \ |
| 6498 V(Math, round, MathRound) \ | 6493 V(Math, round, MathRound) \ |
| 6499 V(Math, ceil, MathCeil) \ | 6494 V(Math, ceil, MathCeil) \ |
| 6500 V(Math, abs, MathAbs) \ | 6495 V(Math, abs, MathAbs) \ |
| 6501 V(Math, log, MathLog) \ | 6496 V(Math, log, MathLog) \ |
| 6502 V(Math, sin, MathSin) \ | |
| 6503 V(Math, cos, MathCos) \ | |
| 6504 V(Math, tan, MathTan) \ | |
| 6505 V(Math, asin, MathASin) \ | |
| 6506 V(Math, acos, MathACos) \ | |
| 6507 V(Math, atan, MathATan) \ | |
| 6508 V(Math, exp, MathExp) \ | 6497 V(Math, exp, MathExp) \ |
| 6509 V(Math, sqrt, MathSqrt) \ | 6498 V(Math, sqrt, MathSqrt) \ |
| 6510 V(Math, pow, MathPow) \ | 6499 V(Math, pow, MathPow) \ |
| 6511 V(Math, max, MathMax) \ | 6500 V(Math, max, MathMax) \ |
| 6512 V(Math, min, MathMin) \ | 6501 V(Math, min, MathMin) \ |
| 6513 V(Math, imul, MathImul) | 6502 V(Math, imul, MathImul) |
| 6514 | 6503 |
| 6515 enum BuiltinFunctionId { | 6504 enum BuiltinFunctionId { |
| 6516 kArrayCode, | 6505 kArrayCode, |
| 6517 #define DECLARE_FUNCTION_ID(ignored1, ignore2, name) \ | 6506 #define DECLARE_FUNCTION_ID(ignored1, ignore2, name) \ |
| (...skipping 1580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8098 enum AllocationSiteMode { | 8087 enum AllocationSiteMode { |
| 8099 DONT_TRACK_ALLOCATION_SITE, | 8088 DONT_TRACK_ALLOCATION_SITE, |
| 8100 TRACK_ALLOCATION_SITE, | 8089 TRACK_ALLOCATION_SITE, |
| 8101 LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE | 8090 LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE |
| 8102 }; | 8091 }; |
| 8103 | 8092 |
| 8104 | 8093 |
| 8105 class AllocationSite: public Struct { | 8094 class AllocationSite: public Struct { |
| 8106 public: | 8095 public: |
| 8107 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024; | 8096 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024; |
| 8097 static const double kPretenureRatio; |
| 8098 static const int kPretenureMinimumCreated = 100; |
| 8099 |
| 8100 // Values for pretenure decision field. |
| 8101 enum { |
| 8102 kUndecided = 0, |
| 8103 kDontTenure = 1, |
| 8104 kTenure = 2, |
| 8105 kZombie = 3 |
| 8106 }; |
| 8108 | 8107 |
| 8109 DECL_ACCESSORS(transition_info, Object) | 8108 DECL_ACCESSORS(transition_info, Object) |
| 8110 // nested_site threads a list of sites that represent nested literals | 8109 // nested_site threads a list of sites that represent nested literals |
| 8111 // walked in a particular order. So [[1, 2], 1, 2] will have one | 8110 // walked in a particular order. So [[1, 2], 1, 2] will have one |
| 8112 // nested_site, but [[1, 2], 3, [4]] will have a list of two. | 8111 // nested_site, but [[1, 2], 3, [4]] will have a list of two. |
| 8113 DECL_ACCESSORS(nested_site, Object) | 8112 DECL_ACCESSORS(nested_site, Object) |
| 8114 DECL_ACCESSORS(memento_found_count, Smi) | 8113 DECL_ACCESSORS(memento_found_count, Smi) |
| 8115 DECL_ACCESSORS(memento_create_count, Smi) | 8114 DECL_ACCESSORS(memento_create_count, Smi) |
| 8115 // TODO(mvstanton): we don't need a whole integer to record pretenure |
| 8116 // decision. Consider sharing space with memento_found_count. |
| 8116 DECL_ACCESSORS(pretenure_decision, Smi) | 8117 DECL_ACCESSORS(pretenure_decision, Smi) |
| 8117 DECL_ACCESSORS(dependent_code, DependentCode) | 8118 DECL_ACCESSORS(dependent_code, DependentCode) |
| 8118 DECL_ACCESSORS(weak_next, Object) | 8119 DECL_ACCESSORS(weak_next, Object) |
| 8119 | 8120 |
| 8120 inline void Initialize(); | 8121 inline void Initialize(); |
| 8121 | 8122 |
| 8122 bool HasNestedSites() { | |
| 8123 return nested_site()->IsAllocationSite(); | |
| 8124 } | |
| 8125 | |
| 8126 // This method is expensive, it should only be called for reporting. | 8123 // This method is expensive, it should only be called for reporting. |
| 8127 bool IsNestedSite(); | 8124 bool IsNestedSite(); |
| 8128 | 8125 |
| 8129 class ElementsKindBits: public BitField<ElementsKind, 0, 15> {}; | 8126 class ElementsKindBits: public BitField<ElementsKind, 0, 15> {}; |
| 8130 class UnusedBits: public BitField<int, 15, 14> {}; | 8127 class UnusedBits: public BitField<int, 15, 14> {}; |
| 8131 class DoNotInlineBit: public BitField<bool, 29, 1> {}; | 8128 class DoNotInlineBit: public BitField<bool, 29, 1> {}; |
| 8132 | 8129 |
| 8130 inline void IncrementMementoFoundCount(); |
| 8131 |
| 8132 inline void IncrementMementoCreateCount(); |
| 8133 |
| 8134 PretenureFlag GetPretenureMode() { |
| 8135 int mode = pretenure_decision()->value(); |
| 8136 // Zombie objects "decide" to be untenured. |
| 8137 return (mode == kTenure) ? TENURED : NOT_TENURED; |
| 8138 } |
| 8139 |
| 8140 // The pretenuring decision is made during gc, and the zombie state allows |
| 8141 // us to recognize when an allocation site is just being kept alive because |
| 8142 // a later traversal of new space may discover AllocationMementos that point |
| 8143 // to this AllocationSite. |
| 8144 bool IsZombie() { |
| 8145 return pretenure_decision()->value() == kZombie; |
| 8146 } |
| 8147 |
| 8148 inline void MarkZombie(); |
| 8149 |
| 8150 inline bool DigestPretenuringFeedback(); |
| 8151 |
| 8133 ElementsKind GetElementsKind() { | 8152 ElementsKind GetElementsKind() { |
| 8134 ASSERT(!SitePointsToLiteral()); | 8153 ASSERT(!SitePointsToLiteral()); |
| 8135 int value = Smi::cast(transition_info())->value(); | 8154 int value = Smi::cast(transition_info())->value(); |
| 8136 return ElementsKindBits::decode(value); | 8155 return ElementsKindBits::decode(value); |
| 8137 } | 8156 } |
| 8138 | 8157 |
| 8139 void SetElementsKind(ElementsKind kind) { | 8158 void SetElementsKind(ElementsKind kind) { |
| 8140 int value = Smi::cast(transition_info())->value(); | 8159 int value = Smi::cast(transition_info())->value(); |
| 8141 set_transition_info(Smi::FromInt(ElementsKindBits::update(value, kind)), | 8160 set_transition_info(Smi::FromInt(ElementsKindBits::update(value, kind)), |
| 8142 SKIP_WRITE_BARRIER); | 8161 SKIP_WRITE_BARRIER); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8196 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset; | 8215 static const int kPointerFieldsBeginOffset = kTransitionInfoOffset; |
| 8197 static const int kPointerFieldsEndOffset = kDependentCodeOffset; | 8216 static const int kPointerFieldsEndOffset = kDependentCodeOffset; |
| 8198 | 8217 |
| 8199 // For other visitors, use the fixed body descriptor below. | 8218 // For other visitors, use the fixed body descriptor below. |
| 8200 typedef FixedBodyDescriptor<HeapObject::kHeaderSize, | 8219 typedef FixedBodyDescriptor<HeapObject::kHeaderSize, |
| 8201 kDependentCodeOffset + kPointerSize, | 8220 kDependentCodeOffset + kPointerSize, |
| 8202 kSize> BodyDescriptor; | 8221 kSize> BodyDescriptor; |
| 8203 | 8222 |
| 8204 private: | 8223 private: |
| 8205 inline DependentCode::DependencyGroup ToDependencyGroup(Reason reason); | 8224 inline DependentCode::DependencyGroup ToDependencyGroup(Reason reason); |
| 8225 bool PretenuringDecisionMade() { |
| 8226 return pretenure_decision()->value() != kUndecided; |
| 8227 } |
| 8228 |
| 8206 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite); | 8229 DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite); |
| 8207 }; | 8230 }; |
| 8208 | 8231 |
| 8209 | 8232 |
| 8210 class AllocationMemento: public Struct { | 8233 class AllocationMemento: public Struct { |
| 8211 public: | 8234 public: |
| 8212 static const int kAllocationSiteOffset = HeapObject::kHeaderSize; | 8235 static const int kAllocationSiteOffset = HeapObject::kHeaderSize; |
| 8213 static const int kSize = kAllocationSiteOffset + kPointerSize; | 8236 static const int kSize = kAllocationSiteOffset + kPointerSize; |
| 8214 | 8237 |
| 8215 DECL_ACCESSORS(allocation_site, Object) | 8238 DECL_ACCESSORS(allocation_site, Object) |
| 8216 | 8239 |
| 8217 bool IsValid() { return allocation_site()->IsAllocationSite(); } | 8240 bool IsValid() { |
| 8241 return allocation_site()->IsAllocationSite() && |
| 8242 !AllocationSite::cast(allocation_site())->IsZombie(); |
| 8243 } |
| 8218 AllocationSite* GetAllocationSite() { | 8244 AllocationSite* GetAllocationSite() { |
| 8219 ASSERT(IsValid()); | 8245 ASSERT(IsValid()); |
| 8220 return AllocationSite::cast(allocation_site()); | 8246 return AllocationSite::cast(allocation_site()); |
| 8221 } | 8247 } |
| 8222 | 8248 |
| 8223 DECLARE_PRINTER(AllocationMemento) | 8249 DECLARE_PRINTER(AllocationMemento) |
| 8224 DECLARE_VERIFIER(AllocationMemento) | 8250 DECLARE_VERIFIER(AllocationMemento) |
| 8225 | 8251 |
| 8226 // Returns NULL if no AllocationMemento is available for object. | 8252 // Returns NULL if no AllocationMemento is available for object. |
| 8227 static AllocationMemento* FindForJSObject(JSObject* object, | 8253 static AllocationMemento* FindForJSObject(JSObject* object, |
| (...skipping 2352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10580 } else { | 10606 } else { |
| 10581 value &= ~(1 << bit_position); | 10607 value &= ~(1 << bit_position); |
| 10582 } | 10608 } |
| 10583 return value; | 10609 return value; |
| 10584 } | 10610 } |
| 10585 }; | 10611 }; |
| 10586 | 10612 |
| 10587 } } // namespace v8::internal | 10613 } } // namespace v8::internal |
| 10588 | 10614 |
| 10589 #endif // V8_OBJECTS_H_ | 10615 #endif // V8_OBJECTS_H_ |
| OLD | NEW |