aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/ic.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ic.h')
-rw-r--r--deps/v8/src/ic.h356
1 files changed, 187 insertions, 169 deletions
diff --git a/deps/v8/src/ic.h b/deps/v8/src/ic.h
index 8f09e1d0a2..fde4bc77a5 100644
--- a/deps/v8/src/ic.h
+++ b/deps/v8/src/ic.h
@@ -57,8 +57,8 @@ namespace internal {
ICU(LoadPropertyWithInterceptorForCall) \
ICU(KeyedLoadPropertyWithInterceptor) \
ICU(StoreInterceptorProperty) \
- ICU(BinaryOp_Patch) \
ICU(CompareIC_Miss) \
+ ICU(BinaryOpIC_Miss) \
ICU(CompareNilIC_Miss) \
ICU(Unreachable) \
ICU(ToBooleanIC_Miss)
@@ -95,11 +95,17 @@ class IC {
virtual ~IC() {}
// Get the call-site target; used for determining the state.
- Code* target() const { return GetTargetAtAddress(address()); }
+ Handle<Code> target() const { return target_; }
+ Code* raw_target() const { return GetTargetAtAddress(address()); }
+
+ State state() const { return state_; }
inline Address address() const;
// Compute the current IC state based on the target stub, receiver and name.
- static State StateFrom(Code* target, Object* receiver, Object* name);
+ void UpdateState(Handle<Object> receiver, Handle<Object> name);
+ void MarkMonomorphicPrototypeFailure() {
+ state_ = MONOMORPHIC_PROTOTYPE_FAILURE;
+ }
// Clear the inline cache to initial state.
static void Clear(Isolate* isolate, Address address);
@@ -128,12 +134,15 @@ class IC {
// These methods should not be called with undefined or null.
static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object,
JSObject* holder);
- static inline InlineCacheHolderFlag GetCodeCacheForObject(JSObject* object,
- JSObject* holder);
static inline JSObject* GetCodeCacheHolder(Isolate* isolate,
Object* object,
InlineCacheHolderFlag holder);
+ static bool IsCleared(Code* code) {
+ InlineCacheState state = code->ic_state();
+ return state == UNINITIALIZED || state == PREMONOMORPHIC;
+ }
+
protected:
Address fp() const { return fp_; }
Address pc() const { return *pc_address_; }
@@ -146,15 +155,17 @@ class IC {
#endif
// Set the call-site target.
- void set_target(Code* code) { SetTargetAtAddress(address(), code); }
+ void set_target(Code* code) {
+ SetTargetAtAddress(address(), code);
+ target_set_ = true;
+ }
+
+ bool is_target_set() { return target_set_; }
#ifdef DEBUG
char TransitionMarkFromState(IC::State state);
- void TraceIC(const char* type,
- Handle<Object> name,
- State old_state,
- Code* new_target);
+ void TraceIC(const char* type, Handle<Object> name);
#endif
Failure* TypeError(const char* type,
@@ -167,51 +178,52 @@ class IC {
static inline void SetTargetAtAddress(Address address, Code* target);
static void PostPatching(Address address, Code* target, Code* old_target);
- virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver,
- Handle<Code> handler,
- Handle<String> name,
- StrictModeFlag strict_mode) {
- set_target(*handler);
- }
- bool UpdatePolymorphicIC(State state,
- Handle<HeapObject> receiver,
- Handle<String> name,
- Handle<Code> code,
- StrictModeFlag strict_mode);
-
- virtual Handle<Code> ComputePolymorphicIC(MapHandleList* receiver_maps,
- CodeHandleList* handlers,
- int number_of_valid_maps,
- Handle<Name> name,
- StrictModeFlag strict_mode) {
+ // Compute the handler either by compiling or by retrieving a cached version.
+ Handle<Code> ComputeHandler(LookupResult* lookup,
+ Handle<JSObject> receiver,
+ Handle<String> name,
+ Handle<Object> value = Handle<Code>::null());
+ virtual Handle<Code> CompileHandler(LookupResult* lookup,
+ Handle<JSObject> receiver,
+ Handle<String> name,
+ Handle<Object> value) {
UNREACHABLE();
return Handle<Code>::null();
- };
+ }
+ void UpdateMonomorphicIC(Handle<HeapObject> receiver,
+ Handle<Code> handler,
+ Handle<String> name);
+
+ bool UpdatePolymorphicIC(Handle<HeapObject> receiver,
+ Handle<String> name,
+ Handle<Code> code);
void CopyICToMegamorphicCache(Handle<String> name);
bool IsTransitionedMapOfMonomorphicTarget(Map* receiver_map);
- void PatchCache(State state,
- StrictModeFlag strict_mode,
- Handle<HeapObject> receiver,
+ void PatchCache(Handle<HeapObject> receiver,
Handle<String> name,
Handle<Code> code);
virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code);
- virtual Handle<Code> megamorphic_stub() {
+ virtual Code::Kind kind() const {
UNREACHABLE();
- return Handle<Code>::null();
+ return Code::STUB;
}
- virtual Handle<Code> megamorphic_stub_strict() {
+ virtual Handle<Code> slow_stub() const {
UNREACHABLE();
return Handle<Code>::null();
}
- virtual Handle<Code> generic_stub() const {
+ virtual Handle<Code> megamorphic_stub() {
UNREACHABLE();
return Handle<Code>::null();
}
- virtual Handle<Code> generic_stub_strict() const {
+ virtual Handle<Code> generic_stub() const {
UNREACHABLE();
return Handle<Code>::null();
}
+ virtual StrictModeFlag strict_mode() const { return kNonStrictMode; }
+ bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
+ Handle<String> name);
+ void TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name);
private:
// Frame pointer for the frame that uses (calls) the IC.
@@ -225,6 +237,11 @@ class IC {
Isolate* isolate_;
+ // The original code target that missed.
+ Handle<Code> target_;
+ State state_;
+ bool target_set_;
+
DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
};
@@ -251,31 +268,23 @@ class CallICBase: public IC {
class StringStubState: public BitField<StringStubFeedback, 1, 1> {};
// Returns a JSFunction or a Failure.
- MUST_USE_RESULT MaybeObject* LoadFunction(State state,
- Code::ExtraICState extra_ic_state,
- Handle<Object> object,
+ MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object,
Handle<String> name);
protected:
CallICBase(Code::Kind kind, Isolate* isolate)
: IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {}
- bool TryUpdateExtraICState(LookupResult* lookup,
- Handle<Object> object,
- Code::ExtraICState* extra_ic_state);
+ virtual Code::ExtraICState extra_ic_state() { return Code::kNoExtraICState; }
// Compute a monomorphic stub if possible, otherwise return a null handle.
Handle<Code> ComputeMonomorphicStub(LookupResult* lookup,
- State state,
- Code::ExtraICState extra_state,
Handle<Object> object,
Handle<String> name);
// Update the inline cache and the global stub cache based on the lookup
// result.
void UpdateCaches(LookupResult* lookup,
- State state,
- Code::ExtraICState extra_ic_state,
Handle<Object> object,
Handle<String> name);
@@ -302,6 +311,9 @@ class CallICBase: public IC {
Code::Kind kind,
Code::ExtraICState extra_state);
+ virtual Handle<Code> megamorphic_stub();
+ virtual Handle<Code> pre_monomorphic_stub();
+
Code::Kind kind_;
friend class IC;
@@ -310,7 +322,9 @@ class CallICBase: public IC {
class CallIC: public CallICBase {
public:
- explicit CallIC(Isolate* isolate) : CallICBase(Code::CALL_IC, isolate) {
+ explicit CallIC(Isolate* isolate)
+ : CallICBase(Code::CALL_IC, isolate),
+ extra_ic_state_(target()->extra_ic_state()) {
ASSERT(target()->is_call_stub());
}
@@ -335,6 +349,13 @@ class CallIC: public CallICBase {
CallICBase::GenerateNormal(masm, argc);
GenerateMiss(masm, argc, Code::kNoExtraICState);
}
+ bool TryUpdateExtraICState(LookupResult* lookup, Handle<Object> object);
+
+ protected:
+ virtual Code::ExtraICState extra_ic_state() { return extra_ic_state_; }
+
+ private:
+ Code::ExtraICState extra_ic_state_;
};
@@ -345,8 +366,7 @@ class KeyedCallIC: public CallICBase {
ASSERT(target()->is_keyed_call_stub());
}
- MUST_USE_RESULT MaybeObject* LoadFunction(State state,
- Handle<Object> object,
+ MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object,
Handle<Object> key);
// Code generator routines.
@@ -381,8 +401,7 @@ class LoadIC: public IC {
static void GenerateNormal(MacroAssembler* masm);
static void GenerateRuntimeGetProperty(MacroAssembler* masm);
- MUST_USE_RESULT MaybeObject* Load(State state,
- Handle<Object> object,
+ MUST_USE_RESULT MaybeObject* Load(Handle<Object> object,
Handle<String> name);
protected:
@@ -399,34 +418,33 @@ class LoadIC: public IC {
// Update the inline cache and the global stub cache based on the
// lookup result.
void UpdateCaches(LookupResult* lookup,
- State state,
Handle<Object> object,
Handle<String> name);
- virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver,
- Handle<Code> handler,
- Handle<String> name,
- StrictModeFlag strict_mode);
-
- virtual Handle<Code> ComputePolymorphicIC(MapHandleList* receiver_maps,
- CodeHandleList* handlers,
- int number_of_valid_maps,
- Handle<Name> name,
- StrictModeFlag strict_mode);
-
- virtual Handle<Code> ComputeLoadHandler(LookupResult* lookup,
- Handle<JSObject> receiver,
- Handle<String> name);
+ virtual Handle<Code> CompileHandler(LookupResult* lookup,
+ Handle<JSObject> receiver,
+ Handle<String> name,
+ Handle<Object> unused);
private:
// Stub accessors.
static Handle<Code> initialize_stub(Isolate* isolate) {
return isolate->builtins()->LoadIC_Initialize();
}
+
+ static Handle<Code> pre_monomorphic_stub(Isolate* isolate) {
+ return isolate->builtins()->LoadIC_PreMonomorphic();
+ }
+
virtual Handle<Code> pre_monomorphic_stub() {
- return isolate()->builtins()->LoadIC_PreMonomorphic();
+ return pre_monomorphic_stub(isolate());
}
+ Handle<Code> SimpleFieldLoad(int offset,
+ bool inobject = true,
+ Representation representation =
+ Representation::Tagged());
+
static void Clear(Isolate* isolate, Address address, Code* target);
friend class IC;
@@ -446,8 +464,7 @@ class KeyedLoadIC: public LoadIC {
ASSERT(target()->is_keyed_load_stub());
}
- MUST_USE_RESULT MaybeObject* Load(State state,
- Handle<Object> object,
+ MUST_USE_RESULT MaybeObject* Load(Handle<Object> object,
Handle<Object> key,
ICMissMode force_generic);
@@ -487,14 +504,6 @@ class KeyedLoadIC: public LoadIC {
return isolate()->builtins()->KeyedLoadIC_Slow();
}
- // Update the inline cache.
- virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver,
- Handle<Code> handler,
- Handle<String> name,
- StrictModeFlag strict_mode);
- virtual Handle<Code> ComputeLoadHandler(LookupResult* lookup,
- Handle<JSObject> receiver,
- Handle<String> name);
virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { }
private:
@@ -502,8 +511,11 @@ class KeyedLoadIC: public LoadIC {
static Handle<Code> initialize_stub(Isolate* isolate) {
return isolate->builtins()->KeyedLoadIC_Initialize();
}
+ static Handle<Code> pre_monomorphic_stub(Isolate* isolate) {
+ return isolate->builtins()->KeyedLoadIC_PreMonomorphic();
+ }
virtual Handle<Code> pre_monomorphic_stub() {
- return isolate()->builtins()->KeyedLoadIC_PreMonomorphic();
+ return pre_monomorphic_stub(isolate());
}
Handle<Code> indexed_interceptor_stub() {
return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor();
@@ -523,10 +535,14 @@ class KeyedLoadIC: public LoadIC {
class StoreIC: public IC {
public:
- StoreIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) {
+ StoreIC(FrameDepth depth, Isolate* isolate)
+ : IC(depth, isolate),
+ strict_mode_(Code::GetStrictMode(target()->extra_ic_state())) {
ASSERT(target()->is_store_stub() || target()->is_keyed_store_stub());
}
+ virtual StrictModeFlag strict_mode() const { return strict_mode_; }
+
// Code generators for stub routines. Only called once at startup.
static void GenerateSlow(MacroAssembler* masm);
static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
@@ -541,8 +557,6 @@ class StoreIC: public IC {
StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* Store(
- State state,
- StrictModeFlag strict_mode,
Handle<Object> object,
Handle<String> name,
Handle<Object> value,
@@ -552,58 +566,60 @@ class StoreIC: public IC {
protected:
virtual Code::Kind kind() const { return Code::STORE_IC; }
virtual Handle<Code> megamorphic_stub() {
- return isolate()->builtins()->StoreIC_Megamorphic();
+ if (strict_mode() == kStrictMode) {
+ return isolate()->builtins()->StoreIC_Megamorphic_Strict();
+ } else {
+ return isolate()->builtins()->StoreIC_Megamorphic();
+ }
}
// Stub accessors.
- virtual Handle<Code> megamorphic_stub_strict() {
- return isolate()->builtins()->StoreIC_Megamorphic_Strict();
- }
virtual Handle<Code> generic_stub() const {
- return isolate()->builtins()->StoreIC_Generic();
+ if (strict_mode() == kStrictMode) {
+ return isolate()->builtins()->StoreIC_Generic_Strict();
+ } else {
+ return isolate()->builtins()->StoreIC_Generic();
+ }
}
- virtual Handle<Code> generic_stub_strict() const {
- return isolate()->builtins()->StoreIC_Generic_Strict();
+
+ virtual Handle<Code> slow_stub() const {
+ if (strict_mode() == kStrictMode) {
+ return isolate()->builtins()->StoreIC_Slow_Strict();
+ } else {
+ return isolate()->builtins()->StoreIC_Slow();
+ }
}
- virtual Handle<Code> pre_monomorphic_stub() const {
- return isolate()->builtins()->StoreIC_PreMonomorphic();
+
+ virtual Handle<Code> pre_monomorphic_stub() {
+ return pre_monomorphic_stub(isolate(), strict_mode());
}
- virtual Handle<Code> pre_monomorphic_stub_strict() const {
- return isolate()->builtins()->StoreIC_PreMonomorphic_Strict();
+
+ static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
+ StrictModeFlag strict_mode) {
+ if (strict_mode == kStrictMode) {
+ return isolate->builtins()->StoreIC_PreMonomorphic_Strict();
+ } else {
+ return isolate->builtins()->StoreIC_PreMonomorphic();
+ }
}
+
virtual Handle<Code> global_proxy_stub() {
- return isolate()->builtins()->StoreIC_GlobalProxy();
- }
- virtual Handle<Code> global_proxy_stub_strict() {
- return isolate()->builtins()->StoreIC_GlobalProxy_Strict();
+ if (strict_mode() == kStrictMode) {
+ return isolate()->builtins()->StoreIC_GlobalProxy_Strict();
+ } else {
+ return isolate()->builtins()->StoreIC_GlobalProxy();
+ }
}
- virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver,
- Handle<Code> handler,
- Handle<String> name,
- StrictModeFlag strict_mode);
-
- virtual Handle<Code> ComputePolymorphicIC(MapHandleList* receiver_maps,
- CodeHandleList* handlers,
- int number_of_valid_maps,
- Handle<Name> name,
- StrictModeFlag strict_mode);
-
// Update the inline cache and the global stub cache based on the
// lookup result.
void UpdateCaches(LookupResult* lookup,
- State state,
- StrictModeFlag strict_mode,
Handle<JSObject> receiver,
Handle<String> name,
Handle<Object> value);
- // Compute the code stub for this store; used for rewriting to
- // monomorphic state and making sure that the code stub is in the
- // stub cache.
- virtual Handle<Code> ComputeStoreMonomorphic(LookupResult* lookup,
- StrictModeFlag strict_mode,
- Handle<JSObject> receiver,
- Handle<String> name,
- Handle<Object> value);
+ virtual Handle<Code> CompileHandler(LookupResult* lookup,
+ Handle<JSObject> receiver,
+ Handle<String> name,
+ Handle<Object> value);
private:
void set_target(Code* code) {
@@ -613,14 +629,19 @@ class StoreIC: public IC {
IC::set_target(code);
}
- static Handle<Code> initialize_stub(Isolate* isolate) {
- return isolate->builtins()->StoreIC_Initialize();
- }
- static Handle<Code> initialize_stub_strict(Isolate* isolate) {
- return isolate->builtins()->StoreIC_Initialize_Strict();
+ static Handle<Code> initialize_stub(Isolate* isolate,
+ StrictModeFlag strict_mode) {
+ if (strict_mode == kStrictMode) {
+ return isolate->builtins()->StoreIC_Initialize_Strict();
+ } else {
+ return isolate->builtins()->StoreIC_Initialize();
+ }
}
+
static void Clear(Isolate* isolate, Address address, Code* target);
+ StrictModeFlag strict_mode_;
+
friend class IC;
};
@@ -644,9 +665,7 @@ class KeyedStoreIC: public StoreIC {
ASSERT(target()->is_keyed_store_stub());
}
- MUST_USE_RESULT MaybeObject* Store(State state,
- StrictModeFlag strict_mode,
- Handle<Object> object,
+ MUST_USE_RESULT MaybeObject* Store(Handle<Object> object,
Handle<Object> name,
Handle<Object> value,
ICMissMode force_generic);
@@ -668,56 +687,62 @@ class KeyedStoreIC: public StoreIC {
protected:
virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
- virtual Handle<Code> ComputeStoreMonomorphic(LookupResult* lookup,
- StrictModeFlag strict_mode,
- Handle<JSObject> receiver,
- Handle<String> name,
- Handle<Object> value);
virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { }
- virtual Handle<Code> pre_monomorphic_stub() const {
- return isolate()->builtins()->KeyedStoreIC_PreMonomorphic();
+ virtual Handle<Code> pre_monomorphic_stub() {
+ return pre_monomorphic_stub(isolate(), strict_mode());
}
- virtual Handle<Code> pre_monomorphic_stub_strict() const {
- return isolate()->builtins()->KeyedStoreIC_PreMonomorphic_Strict();
+ static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
+ StrictModeFlag strict_mode) {
+ if (strict_mode == kStrictMode) {
+ return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict();
+ } else {
+ return isolate->builtins()->KeyedStoreIC_PreMonomorphic();
+ }
}
- virtual Handle<Code> megamorphic_stub() {
- return isolate()->builtins()->KeyedStoreIC_Generic();
+ virtual Handle<Code> slow_stub() const {
+ if (strict_mode() == kStrictMode) {
+ return isolate()->builtins()->KeyedStoreIC_Slow_Strict();
+ } else {
+ return isolate()->builtins()->KeyedStoreIC_Slow();
+ }
}
- virtual Handle<Code> megamorphic_stub_strict() {
- return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
+ virtual Handle<Code> megamorphic_stub() {
+ if (strict_mode() == kStrictMode) {
+ return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
+ } else {
+ return isolate()->builtins()->KeyedStoreIC_Generic();
+ }
}
Handle<Code> StoreElementStub(Handle<JSObject> receiver,
- KeyedAccessStoreMode store_mode,
- StrictModeFlag strict_mode);
-
- virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver,
- Handle<Code> handler,
- Handle<String> name,
- StrictModeFlag strict_mode);
+ KeyedAccessStoreMode store_mode);
private:
void set_target(Code* code) {
// Strict mode must be preserved across IC patching.
- ASSERT(Code::GetStrictMode(code->extra_ic_state()) ==
- Code::GetStrictMode(target()->extra_ic_state()));
+ ASSERT(Code::GetStrictMode(code->extra_ic_state()) == strict_mode());
IC::set_target(code);
}
// Stub accessors.
- static Handle<Code> initialize_stub(Isolate* isolate) {
- return isolate->builtins()->KeyedStoreIC_Initialize();
- }
- static Handle<Code> initialize_stub_strict(Isolate* isolate) {
- return isolate->builtins()->KeyedStoreIC_Initialize_Strict();
- }
- Handle<Code> generic_stub() const {
- return isolate()->builtins()->KeyedStoreIC_Generic();
+ static Handle<Code> initialize_stub(Isolate* isolate,
+ StrictModeFlag strict_mode) {
+ if (strict_mode == kStrictMode) {
+ return isolate->builtins()->KeyedStoreIC_Initialize_Strict();
+ } else {
+ return isolate->builtins()->KeyedStoreIC_Initialize();
+ }
}
- Handle<Code> generic_stub_strict() const {
- return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
+
+ virtual Handle<Code> generic_stub() const {
+ if (strict_mode() == kStrictMode) {
+ return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
+ } else {
+ return isolate()->builtins()->KeyedStoreIC_Generic();
+ }
}
+
Handle<Code> non_strict_arguments_stub() {
return isolate()->builtins()->KeyedStoreIC_NonStrictArguments();
}
@@ -748,22 +773,14 @@ class BinaryOpIC: public IC {
GENERIC
};
- static void StubInfoToType(int minor_key,
- Handle<Type>* left,
- Handle<Type>* right,
- Handle<Type>* result,
- Isolate* isolate);
-
- explicit BinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { }
+ explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { }
- void patch(Code* code);
+ static Builtins::JavaScript TokenToJSBuiltin(Token::Value op);
static const char* GetName(TypeInfo type_info);
- static State ToState(TypeInfo type_info);
-
- private:
- static Handle<Type> TypeInfoToType(TypeInfo binary_type, Isolate* isolate);
+ MUST_USE_RESULT MaybeObject* Transition(Handle<Object> left,
+ Handle<Object> right);
};
@@ -870,6 +887,7 @@ DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure);
DECLARE_RUNTIME_FUNCTION(MaybeObject*, UnaryOpIC_Miss);
DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure);
DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss);
+DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss);
DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss);
DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss);