Index: src/ic.h |
diff --git a/src/ic.h b/src/ic.h |
index 213a48182635badf5c833729e0d8d143e999b6c8..8e2890bfad09853e0d0b23804ba2a66c6bc0bb06 100644 |
--- a/src/ic.h |
+++ b/src/ic.h |
@@ -42,6 +42,7 @@ const int kMaxKeyedPolymorphism = 4; |
#define IC_UTIL_LIST(ICU) \ |
ICU(LoadIC_Miss) \ |
ICU(KeyedLoadIC_Miss) \ |
+ ICU(CallIC_Miss) \ |
ICU(StoreIC_Miss) \ |
ICU(StoreIC_ArrayLength) \ |
ICU(StoreIC_Slow) \ |
@@ -111,6 +112,10 @@ class IC { |
bool IsStoreStub() const { |
return target()->is_store_stub() || target()->is_keyed_store_stub(); |
} |
+ |
+ bool IsCallStub() const { |
+ return target()->is_call_stub(); |
+ } |
#endif |
// Determines which map must be used for keeping the code stub. |
@@ -280,6 +285,93 @@ class IC_Utility { |
}; |
+class CallIC: public IC { |
+ public: |
+ enum CallType { METHOD, FUNCTION }; |
+ enum StubType { GENERIC, MONOMORPHIC }; |
+ enum ArgumentCheck { ARGUMENTS_MATCH, ARGUMENTS_DONT_MATCH }; |
+ enum FunctionAttributes { NOT_STRICT_OR_NATIVE, STRICT_OR_NATIVE }; |
+ |
+ class State V8_FINAL BASE_EMBEDDED { |
+ public: |
+ explicit State(ExtraICState extra_ic_state); |
+ |
+ State(int argc, |
+ CallType call_type, |
+ StubType stub_type = GENERIC, |
+ ArgumentCheck argument_check = ARGUMENTS_MATCH, |
+ FunctionAttributes attributes = NOT_STRICT_OR_NATIVE) |
+ : argc_(argc), |
+ call_type_(call_type), |
+ stub_type_(stub_type), |
+ argument_check_(argument_check), |
+ function_attributes_(attributes) { |
+ } |
+ |
+ InlineCacheState GetICState() const { |
+ return stub_type_ == CallIC::MONOMORPHIC |
+ ? ::v8::internal::MONOMORPHIC |
+ : ::v8::internal::GENERIC; |
+ } |
+ |
+ ExtraICState GetExtraICState() const; |
+ |
+ static void GenerateAheadOfTime( |
+ Isolate*, void (*Generate)(Isolate*, const State&)); |
+ |
+ int arg_count() const { return argc_; } |
+ |
+ CallType call_type() const { return call_type_; } |
+ StubType stub_type() const { return stub_type_; } |
+ ArgumentCheck argument_check() const { return argument_check_; } |
+ FunctionAttributes function_attributes() const { |
+ return function_attributes_; |
+ } |
+ |
+ void Print(StringStream* stream) const; |
+ |
+ private: |
+ class ArgBits: public BitField<int, 0, Code::kArgumentsBits> {}; |
+ class CallTypeBits: public BitField<CallType, Code::kArgumentsBits, 1> {}; |
+ class StubTypeBits: |
+ public BitField<StubType, Code::kArgumentsBits + 1, 1> {}; // NOLINT |
+ class ArgumentCheckBits: |
+ public BitField<ArgumentCheck, |
+ Code::kArgumentsBits + 2, 1> {}; // NOLINT |
+ class FunctionAttributeBits: |
+ public BitField<FunctionAttributes, |
+ Code::kArgumentsBits + 3, 1> {}; // NOLINT |
+ |
+ int argc_; |
+ CallType call_type_; |
+ StubType stub_type_; |
+ ArgumentCheck argument_check_; |
+ FunctionAttributes function_attributes_; |
+ }; |
+ |
+ explicit CallIC(Isolate* isolate) |
+ : IC(EXTRA_CALL_FRAME, isolate) { |
+ } |
+ |
+ void HandleMiss(Handle<Object> receiver, |
+ Handle<Object> function, |
+ Handle<FixedArray> vector, |
+ Handle<Smi> slot); |
+ |
+ // Code generator routines. |
+ static void GenerateNormal(MacroAssembler* masm, int argc, |
+ CallType call_type); |
+ static Handle<Code> initialize_stub(Isolate* isolate, |
+ int argc, |
+ CallType call_type); |
+ |
+ static void Clear(Isolate* isolate, Address address, Code* target); |
+ |
+ private: |
+ void PatchMegamorphic(int arg_count, CallType call_type); |
+}; |
+ |
+ |
class LoadIC: public IC { |
public: |
// ExtraICState bits |