| Index: src/ic.h | 
| diff --git a/src/ic.h b/src/ic.h | 
| index d2c98c0869799e5fc5e8e81a40a4ced4ff995eeb..5711a483b05c9341bec4ac13b68226d471e5e3b3 100644 | 
| --- a/src/ic.h | 
| +++ b/src/ic.h | 
| @@ -1,4 +1,4 @@ | 
| -// Copyright 2011 the V8 project authors. All rights reserved. | 
| +// Copyright 2012 the V8 project authors. All rights reserved. | 
| // Redistribution and use in source and binary forms, with or without | 
| // modification, are permitted provided that the following conditions are | 
| // met: | 
| @@ -377,14 +377,48 @@ class KeyedIC: public IC { | 
| STORE_NO_TRANSITION, | 
| STORE_TRANSITION_SMI_TO_OBJECT, | 
| STORE_TRANSITION_SMI_TO_DOUBLE, | 
| -    STORE_TRANSITION_DOUBLE_TO_OBJECT | 
| +    STORE_TRANSITION_DOUBLE_TO_OBJECT, | 
| +    STORE_AND_GROW_NO_TRANSITION, | 
| +    STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT, | 
| +    STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE, | 
| +    STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT | 
| }; | 
| + | 
| +  static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION - | 
| +      STORE_NO_TRANSITION; | 
| +  STATIC_ASSERT(kGrowICDelta == | 
| +                STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT - | 
| +                STORE_TRANSITION_SMI_TO_OBJECT); | 
| +  STATIC_ASSERT(kGrowICDelta == | 
| +                STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE - | 
| +                STORE_TRANSITION_SMI_TO_DOUBLE); | 
| +  STATIC_ASSERT(kGrowICDelta == | 
| +                STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT - | 
| +                STORE_TRANSITION_DOUBLE_TO_OBJECT); | 
| + | 
| explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {} | 
| virtual ~KeyedIC() {} | 
|  | 
| +  static inline KeyedAccessGrowMode GetGrowModeFromStubKind( | 
| +      StubKind stub_kind) { | 
| +    return (stub_kind >= STORE_AND_GROW_NO_TRANSITION) | 
| +        ? ALLOW_JSARRAY_GROWTH | 
| +        : DO_NOT_ALLOW_JSARRAY_GROWTH; | 
| +  } | 
| + | 
| +  static inline StubKind GetGrowStubKind(StubKind stub_kind) { | 
| +    ASSERT(stub_kind != LOAD); | 
| +    if (stub_kind < STORE_AND_GROW_NO_TRANSITION) { | 
| +      stub_kind = static_cast<StubKind>(static_cast<int>(stub_kind) + | 
| +                                        kGrowICDelta); | 
| +    } | 
| +    return stub_kind; | 
| +  } | 
| + | 
| virtual Handle<Code> GetElementStubWithoutMapCheck( | 
| bool is_js_array, | 
| -      ElementsKind elements_kind) = 0; | 
| +      ElementsKind elements_kind, | 
| +      KeyedAccessGrowMode grow_mode) = 0; | 
|  | 
| protected: | 
| virtual Handle<Code> string_stub() { | 
| @@ -398,12 +432,15 @@ class KeyedIC: public IC { | 
| StrictModeFlag strict_mode, | 
| Handle<Code> default_stub); | 
|  | 
| -  virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps, | 
| -                                              StrictModeFlag strict_mode) = 0; | 
| +  virtual Handle<Code> ComputePolymorphicStub( | 
| +      MapHandleList* receiver_maps, | 
| +      StrictModeFlag strict_mode, | 
| +      KeyedAccessGrowMode grow_mode) = 0; | 
|  | 
| Handle<Code> ComputeMonomorphicStubWithoutMapCheck( | 
| Handle<Map> receiver_map, | 
| -      StrictModeFlag strict_mode); | 
| +      StrictModeFlag strict_mode, | 
| +      KeyedAccessGrowMode grow_mode); | 
|  | 
| private: | 
| void GetReceiverMapsForStub(Handle<Code> stub, MapHandleList* result); | 
| @@ -417,7 +454,12 @@ class KeyedIC: public IC { | 
| StubKind stub_kind); | 
|  | 
| static bool IsTransitionStubKind(StubKind stub_kind) { | 
| -    return stub_kind > STORE_NO_TRANSITION; | 
| +    return stub_kind > STORE_NO_TRANSITION && | 
| +        stub_kind != STORE_AND_GROW_NO_TRANSITION; | 
| +  } | 
| + | 
| +  static bool IsGrowStubKind(StubKind stub_kind) { | 
| +    return stub_kind >= STORE_AND_GROW_NO_TRANSITION; | 
| } | 
| }; | 
|  | 
| @@ -456,7 +498,8 @@ class KeyedLoadIC: public KeyedIC { | 
|  | 
| virtual Handle<Code> GetElementStubWithoutMapCheck( | 
| bool is_js_array, | 
| -      ElementsKind elements_kind); | 
| +      ElementsKind elements_kind, | 
| +      KeyedAccessGrowMode grow_mode); | 
|  | 
| virtual bool IsGeneric() const { | 
| return target() == *generic_stub(); | 
| @@ -466,7 +509,8 @@ class KeyedLoadIC: public KeyedIC { | 
| virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } | 
|  | 
| virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps, | 
| -                                              StrictModeFlag strict_mode); | 
| +                                              StrictModeFlag strict_mode, | 
| +                                              KeyedAccessGrowMode grow_mode); | 
|  | 
| virtual Handle<Code> string_stub() { | 
| return isolate()->builtins()->KeyedLoadIC_String(); | 
| @@ -540,8 +584,8 @@ class StoreIC: public IC { | 
|  | 
| void set_target(Code* code) { | 
| // Strict mode must be preserved across IC patching. | 
| -    ASSERT((code->extra_ic_state() & kStrictMode) == | 
| -           (target()->extra_ic_state() & kStrictMode)); | 
| +    ASSERT(Code::GetStrictMode(code->extra_ic_state()) == | 
| +           Code::GetStrictMode(target()->extra_ic_state())); | 
| IC::set_target(code); | 
| } | 
|  | 
| @@ -603,7 +647,8 @@ class KeyedStoreIC: public KeyedIC { | 
|  | 
| virtual Handle<Code> GetElementStubWithoutMapCheck( | 
| bool is_js_array, | 
| -      ElementsKind elements_kind); | 
| +      ElementsKind elements_kind, | 
| +      KeyedAccessGrowMode grow_mode); | 
|  | 
| virtual bool IsGeneric() const { | 
| return target() == *generic_stub() || | 
| @@ -614,7 +659,8 @@ class KeyedStoreIC: public KeyedIC { | 
| virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } | 
|  | 
| virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps, | 
| -                                              StrictModeFlag strict_mode); | 
| +                                              StrictModeFlag strict_mode, | 
| +                                              KeyedAccessGrowMode grow_mode); | 
|  | 
| private: | 
| // Update the inline cache. | 
| @@ -627,8 +673,8 @@ class KeyedStoreIC: public KeyedIC { | 
|  | 
| void set_target(Code* code) { | 
| // Strict mode must be preserved across IC patching. | 
| -    ASSERT((code->extra_ic_state() & kStrictMode) == | 
| -           (target()->extra_ic_state() & kStrictMode)); | 
| +    ASSERT(Code::GetStrictMode(code->extra_ic_state()) == | 
| +           Code::GetStrictMode(target()->extra_ic_state())); | 
| IC::set_target(code); | 
| } | 
|  | 
| @@ -659,6 +705,10 @@ class KeyedStoreIC: public KeyedIC { | 
|  | 
| static void Clear(Address address, Code* target); | 
|  | 
| +  StubKind GetStubKind(Handle<JSObject> receiver, | 
| +                       Handle<Object> key, | 
| +                       Handle<Object> value); | 
| + | 
| friend class IC; | 
| }; | 
|  | 
|  |