| Index: src/objects.h
|
| diff --git a/src/objects.h b/src/objects.h
|
| index 8e2a831126e341ae564a7ad91dcc7e88cfd54d9e..cc77e1977d3f54f3be1f97f7e15900b6e5c074ac 100644
|
| --- a/src/objects.h
|
| +++ b/src/objects.h
|
| @@ -179,6 +179,12 @@ enum KeyedAccessStoreMode {
|
| };
|
|
|
|
|
| +enum ContextualMode {
|
| + NOT_CONTEXTUAL,
|
| + CONTEXTUAL
|
| +};
|
| +
|
| +
|
| static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION -
|
| STANDARD_STORE;
|
| STATIC_ASSERT(STANDARD_STORE == 0);
|
| @@ -297,10 +303,15 @@ enum MarkingParity {
|
| EVEN_MARKING_PARITY
|
| };
|
|
|
| +// ICs store extra state in a Code object. The default extra state is
|
| +// kNoExtraICState.
|
| +typedef int ExtraICState;
|
| +static const ExtraICState kNoExtraICState = 0;
|
| +
|
| // Instance size sentinel for objects of variable size.
|
| const int kVariableSizeSentinel = 0;
|
|
|
| -const int kStubMajorKeyBits = 6;
|
| +const int kStubMajorKeyBits = 7;
|
| const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits;
|
|
|
| // All Maps have a field instance_type containing a InstanceType.
|
| @@ -861,7 +872,8 @@ enum CompareResult {
|
|
|
| class AccessorPair;
|
| class AllocationSite;
|
| -class AllocationSiteContext;
|
| +class AllocationSiteCreationContext;
|
| +class AllocationSiteUsageContext;
|
| class DictionaryElementsAccessor;
|
| class ElementsAccessor;
|
| class Failure;
|
| @@ -1359,6 +1371,7 @@ class Object : public MaybeObject {
|
|
|
| INLINE(bool IsSpecObject());
|
| INLINE(bool IsSpecFunction());
|
| + bool IsCallable();
|
|
|
| // Oddball testing.
|
| INLINE(bool IsUndefined());
|
| @@ -2521,13 +2534,17 @@ class JSObject: public JSReceiver {
|
| static void SetObserved(Handle<JSObject> object);
|
|
|
| // Copy object.
|
| - static Handle<JSObject> Copy(Handle<JSObject> object,
|
| - Handle<AllocationSite> site);
|
| + enum DeepCopyHints {
|
| + kNoHints = 0,
|
| + kObjectIsShallowArray = 1
|
| + };
|
| +
|
| static Handle<JSObject> Copy(Handle<JSObject> object);
|
| static Handle<JSObject> DeepCopy(Handle<JSObject> object,
|
| - AllocationSiteContext* site_context);
|
| + AllocationSiteUsageContext* site_context,
|
| + DeepCopyHints hints = kNoHints);
|
| static Handle<JSObject> DeepWalk(Handle<JSObject> object,
|
| - AllocationSiteContext* site_context);
|
| + AllocationSiteCreationContext* site_context);
|
|
|
| // Casting.
|
| static inline JSObject* cast(Object* obj);
|
| @@ -2634,9 +2651,6 @@ class JSObject: public JSReceiver {
|
| Handle<Name> name,
|
| Handle<Object> old_value);
|
|
|
| - // Deliver change records to observers. May cause GC.
|
| - static void DeliverChangeRecords(Isolate* isolate);
|
| -
|
| private:
|
| friend class DictionaryElementsAccessor;
|
| friend class JSReceiver;
|
| @@ -5033,10 +5047,6 @@ class Code: public HeapObject {
|
| FAST
|
| };
|
|
|
| - typedef int ExtraICState;
|
| -
|
| - static const ExtraICState kNoExtraICState = 0;
|
| -
|
| static const int kPrologueOffsetNotSet = -1;
|
|
|
| #ifdef ENABLE_DISASSEMBLER
|
| @@ -5149,11 +5159,6 @@ class Code: public HeapObject {
|
| bool is_crankshafted();
|
| inline void set_is_crankshafted(bool value);
|
|
|
| - // For stubs, tells whether they should always exist, so that they can be
|
| - // called from other stubs.
|
| - inline bool is_pregenerated();
|
| - inline void set_is_pregenerated(bool value);
|
| -
|
| // [optimizable]: For FUNCTION kind, tells if it is optimizable.
|
| inline bool optimizable();
|
| inline void set_optimizable(bool value);
|
| @@ -5256,26 +5261,6 @@ class Code: public HeapObject {
|
| // out the to-be-overwritten header data for reproducible snapshots.
|
| inline void WipeOutHeader();
|
|
|
| - class ExtraICStateStrictMode: public BitField<StrictModeFlag, 0, 1> {};
|
| - class ExtraICStateKeyedAccessStoreMode:
|
| - public BitField<KeyedAccessStoreMode, 1, 4> {}; // NOLINT
|
| -
|
| - static inline StrictModeFlag GetStrictMode(ExtraICState extra_ic_state) {
|
| - return ExtraICStateStrictMode::decode(extra_ic_state);
|
| - }
|
| -
|
| - static inline KeyedAccessStoreMode GetKeyedAccessStoreMode(
|
| - ExtraICState extra_ic_state) {
|
| - return ExtraICStateKeyedAccessStoreMode::decode(extra_ic_state);
|
| - }
|
| -
|
| - static inline ExtraICState ComputeExtraICState(
|
| - KeyedAccessStoreMode store_mode,
|
| - StrictModeFlag strict_mode) {
|
| - return ExtraICStateKeyedAccessStoreMode::encode(store_mode) |
|
| - ExtraICStateStrictMode::encode(strict_mode);
|
| - }
|
| -
|
| // Flags operations.
|
| static inline Flags ComputeFlags(
|
| Kind kind,
|
| @@ -5459,12 +5444,12 @@ class Code: public HeapObject {
|
| // Flags layout. BitField<type, shift, size>.
|
| class ICStateField: public BitField<InlineCacheState, 0, 3> {};
|
| class TypeField: public BitField<StubType, 3, 1> {};
|
| - class CacheHolderField: public BitField<InlineCacheHolderFlag, 6, 1> {};
|
| - class KindField: public BitField<Kind, 7, 4> {};
|
| - class IsPregeneratedField: public BitField<bool, 11, 1> {};
|
| - class ExtraICStateField: public BitField<ExtraICState, 12, 5> {};
|
| - class ExtendedExtraICStateField: public BitField<ExtraICState, 12,
|
| - PlatformSmiTagging::kSmiValueSize - 12 + 1> {}; // NOLINT
|
| + class CacheHolderField: public BitField<InlineCacheHolderFlag, 5, 1> {};
|
| + class KindField: public BitField<Kind, 6, 4> {};
|
| + // TODO(bmeurer): Bit 10 is available for free use. :-)
|
| + class ExtraICStateField: public BitField<ExtraICState, 11, 6> {};
|
| + class ExtendedExtraICStateField: public BitField<ExtraICState, 11,
|
| + PlatformSmiTagging::kSmiValueSize - 11 + 1> {}; // NOLINT
|
| STATIC_ASSERT(ExtraICStateField::kShift == ExtendedExtraICStateField::kShift);
|
|
|
| // KindSpecificFlags1 layout (STUB and OPTIMIZED_FUNCTION)
|
| @@ -5499,7 +5484,7 @@ class Code: public HeapObject {
|
| static const int kStubMajorKeyFirstBit = kIsCrankshaftedBit + 1;
|
| static const int kSafepointTableOffsetFirstBit =
|
| kStubMajorKeyFirstBit + kStubMajorKeyBits;
|
| - static const int kSafepointTableOffsetBitCount = 25;
|
| + static const int kSafepointTableOffsetBitCount = 24;
|
|
|
| STATIC_ASSERT(kStubMajorKeyFirstBit + kStubMajorKeyBits <= 32);
|
| STATIC_ASSERT(kSafepointTableOffsetFirstBit +
|
| @@ -6198,6 +6183,16 @@ class Map: public HeapObject {
|
| bool IsJSObjectMap() {
|
| return instance_type() >= FIRST_JS_OBJECT_TYPE;
|
| }
|
| + bool IsJSGlobalProxyMap() {
|
| + return instance_type() == JS_GLOBAL_PROXY_TYPE;
|
| + }
|
| + bool IsJSGlobalObjectMap() {
|
| + return instance_type() == JS_GLOBAL_OBJECT_TYPE;
|
| + }
|
| + bool IsGlobalObjectMap() {
|
| + const InstanceType type = instance_type();
|
| + return type == JS_GLOBAL_OBJECT_TYPE || type == JS_BUILTINS_OBJECT_TYPE;
|
| + }
|
|
|
| // Fires when the layout of an object with a leaf map changes.
|
| // This includes adding transitions to the leaf map or changing
|
| @@ -6499,12 +6494,6 @@ class Script: public Struct {
|
| 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) \
|
| @@ -8105,6 +8094,16 @@ enum AllocationSiteMode {
|
| class AllocationSite: public Struct {
|
| public:
|
| static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024;
|
| + static const double kPretenureRatio;
|
| + static const int kPretenureMinimumCreated = 100;
|
| +
|
| + // Values for pretenure decision field.
|
| + enum {
|
| + kUndecided = 0,
|
| + kDontTenure = 1,
|
| + kTenure = 2,
|
| + kZombie = 3
|
| + };
|
|
|
| DECL_ACCESSORS(transition_info, Object)
|
| // nested_site threads a list of sites that represent nested literals
|
| @@ -8113,16 +8112,14 @@ class AllocationSite: public Struct {
|
| DECL_ACCESSORS(nested_site, Object)
|
| DECL_ACCESSORS(memento_found_count, Smi)
|
| DECL_ACCESSORS(memento_create_count, Smi)
|
| + // TODO(mvstanton): we don't need a whole integer to record pretenure
|
| + // decision. Consider sharing space with memento_found_count.
|
| DECL_ACCESSORS(pretenure_decision, Smi)
|
| DECL_ACCESSORS(dependent_code, DependentCode)
|
| DECL_ACCESSORS(weak_next, Object)
|
|
|
| inline void Initialize();
|
|
|
| - bool HasNestedSites() {
|
| - return nested_site()->IsAllocationSite();
|
| - }
|
| -
|
| // This method is expensive, it should only be called for reporting.
|
| bool IsNestedSite();
|
|
|
| @@ -8130,6 +8127,28 @@ class AllocationSite: public Struct {
|
| class UnusedBits: public BitField<int, 15, 14> {};
|
| class DoNotInlineBit: public BitField<bool, 29, 1> {};
|
|
|
| + inline void IncrementMementoFoundCount();
|
| +
|
| + inline void IncrementMementoCreateCount();
|
| +
|
| + PretenureFlag GetPretenureMode() {
|
| + int mode = pretenure_decision()->value();
|
| + // Zombie objects "decide" to be untenured.
|
| + return (mode == kTenure) ? TENURED : NOT_TENURED;
|
| + }
|
| +
|
| + // The pretenuring decision is made during gc, and the zombie state allows
|
| + // us to recognize when an allocation site is just being kept alive because
|
| + // a later traversal of new space may discover AllocationMementos that point
|
| + // to this AllocationSite.
|
| + bool IsZombie() {
|
| + return pretenure_decision()->value() == kZombie;
|
| + }
|
| +
|
| + inline void MarkZombie();
|
| +
|
| + inline bool DigestPretenuringFeedback();
|
| +
|
| ElementsKind GetElementsKind() {
|
| ASSERT(!SitePointsToLiteral());
|
| int value = Smi::cast(transition_info())->value();
|
| @@ -8203,6 +8222,10 @@ class AllocationSite: public Struct {
|
|
|
| private:
|
| inline DependentCode::DependencyGroup ToDependencyGroup(Reason reason);
|
| + bool PretenuringDecisionMade() {
|
| + return pretenure_decision()->value() != kUndecided;
|
| + }
|
| +
|
| DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationSite);
|
| };
|
|
|
| @@ -8214,7 +8237,10 @@ class AllocationMemento: public Struct {
|
|
|
| DECL_ACCESSORS(allocation_site, Object)
|
|
|
| - bool IsValid() { return allocation_site()->IsAllocationSite(); }
|
| + bool IsValid() {
|
| + return allocation_site()->IsAllocationSite() &&
|
| + !AllocationSite::cast(allocation_site())->IsZombie();
|
| + }
|
| AllocationSite* GetAllocationSite() {
|
| ASSERT(IsValid());
|
| return AllocationSite::cast(allocation_site());
|
|
|