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; |
}; |