Removing ic.h from code-stubs.h
authormvstanton@chromium.org <mvstanton@chromium.org>
Tue, 16 Sep 2014 12:51:33 +0000 (12:51 +0000)
committermvstanton@chromium.org <mvstanton@chromium.org>
Tue, 16 Sep 2014 12:51:33 +0000 (12:51 +0000)
CodeStubs use state types defined in ic.h, but this has the unfortunate effect of spreading ic.h all over the place. Instead, define these shared state types in ic-public.h and allow ic.h to concern itself with internal state change of the ICs.

More work could/should be done here, but this is a first step.

R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/565873002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23977 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

46 files changed:
BUILD.gn
src/arm/code-stubs-arm.cc
src/arm/full-codegen-arm.cc
src/arm/lithium-codegen-arm.cc
src/arm64/code-stubs-arm64.cc
src/arm64/full-codegen-arm64.cc
src/arm64/lithium-codegen-arm64.cc
src/assembler.cc
src/code-factory.cc
src/code-stubs-hydrogen.cc
src/code-stubs.cc
src/code-stubs.h
src/disassembler.cc
src/full-codegen.h
src/heap/mark-compact.cc
src/heap/objects-visiting-inl.h
src/hydrogen.cc
src/hydrogen.h
src/ia32/code-stubs-ia32.cc
src/ia32/full-codegen-ia32.cc
src/ia32/lithium-codegen-ia32.cc
src/ic/arm/handler-compiler-arm.cc
src/ic/arm/ic-compiler-arm.cc
src/ic/arm64/handler-compiler-arm64.cc
src/ic/arm64/ic-compiler-arm64.cc
src/ic/handler-compiler.cc
src/ic/handler-compiler.h
src/ic/ia32/handler-compiler-ia32.cc
src/ic/ia32/ic-compiler-ia32.cc
src/ic/ic-inl.h
src/ic/ic-state.cc [new file with mode: 0644]
src/ic/ic-state.h [new file with mode: 0644]
src/ic/ic.cc
src/ic/ic.h
src/ic/mips/handler-compiler-mips.cc
src/ic/mips/ic-compiler-mips.cc
src/ic/x64/ic-compiler-x64.cc
src/mips/code-stubs-mips.cc
src/mips/full-codegen-mips.cc
src/mips/lithium-codegen-mips.cc
src/objects.cc
src/type-info.cc
src/x64/code-stubs-x64.cc
src/x64/full-codegen-x64.cc
src/x64/lithium-codegen-x64.cc
tools/gyp/v8.gyp

index c8a0b3c..4f95804 100644 (file)
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -731,6 +731,8 @@ source_set("v8_base") {
     "src/ic/handler-compiler.cc",
     "src/ic/handler-compiler.h",
     "src/ic/ic-inl.h",
+    "src/ic/ic-state.cc",
+    "src/ic/ic-state.h",
     "src/ic/ic.cc",
     "src/ic/ic.h",
     "src/ic/ic-compiler.cc",
index 311d0b7..9ad885e 100644 (file)
@@ -11,6 +11,7 @@
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
@@ -566,12 +567,12 @@ static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm,
 
 static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input,
                                          Register scratch,
-                                         CompareIC::State expected,
+                                         CompareICState::State expected,
                                          Label* fail) {
   Label ok;
-  if (expected == CompareIC::SMI) {
+  if (expected == CompareICState::SMI) {
     __ JumpIfNotSmi(input, fail);
-  } else if (expected == CompareIC::NUMBER) {
+  } else if (expected == CompareICState::NUMBER) {
     __ JumpIfSmi(input, &ok);
     __ CheckMap(input, scratch, Heap::kHeapNumberMapRootIndex, fail,
                 DONT_DO_SMI_CHECK);
@@ -2615,7 +2616,7 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
   __ TailCallStub(&stub);
 
   __ bind(&miss);
-  GenerateMiss(masm, IC::kCallIC_Customization_Miss);
+  GenerateMiss(masm);
 
   // The slow case, we need this no matter what to complete a call after a miss.
   CallFunctionNoFeedback(masm,
@@ -2690,7 +2691,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
 
   // We are here because tracing is on or we are going monomorphic.
   __ bind(&miss);
-  GenerateMiss(masm, IC::kCallIC_Miss);
+  GenerateMiss(masm);
 
   // the slow case
   __ bind(&slow_start);
@@ -2705,7 +2706,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
 }
 
 
-void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
+void CallICStub::GenerateMiss(MacroAssembler* masm) {
   // Get the receiver of the function from the stack; 1 ~ return address.
   __ ldr(r4, MemOperand(sp, (arg_count() + 1) * kPointerSize));
 
@@ -2716,6 +2717,9 @@ void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
     __ Push(r4, r1, r2, r3);
 
     // Call the entry.
+    IC::UtilityId id = GetICState() == DEFAULT ? IC::kCallIC_Miss
+                                               : IC::kCallIC_Customization_Miss;
+
     ExternalReference miss = ExternalReference(IC_Utility(id),
                                                masm->isolate());
     __ CallExternalReference(miss, 4);
@@ -3279,7 +3283,7 @@ void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateSmis(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::SMI);
+  DCHECK(state() == CompareICState::SMI);
   Label miss;
   __ orr(r2, r1, r0);
   __ JumpIfNotSmi(r2, &miss);
@@ -3300,16 +3304,16 @@ void CompareICStub::GenerateSmis(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::NUMBER);
+  DCHECK(state() == CompareICState::NUMBER);
 
   Label generic_stub;
   Label unordered, maybe_undefined1, maybe_undefined2;
   Label miss;
 
-  if (left() == CompareIC::SMI) {
+  if (left() == CompareICState::SMI) {
     __ JumpIfNotSmi(r1, &miss);
   }
-  if (right() == CompareIC::SMI) {
+  if (right() == CompareICState::SMI) {
     __ JumpIfNotSmi(r0, &miss);
   }
 
@@ -3351,8 +3355,8 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
 
   __ bind(&unordered);
   __ bind(&generic_stub);
-  CompareICStub stub(isolate(), op(), CompareIC::GENERIC, CompareIC::GENERIC,
-                     CompareIC::GENERIC);
+  CompareICStub stub(isolate(), op(), CompareICState::GENERIC,
+                     CompareICState::GENERIC, CompareICState::GENERIC);
   __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
 
   __ bind(&maybe_undefined1);
@@ -3377,7 +3381,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::INTERNALIZED_STRING);
+  DCHECK(state() == CompareICState::INTERNALIZED_STRING);
   Label miss;
 
   // Registers containing left and right operands respectively.
@@ -3415,7 +3419,7 @@ void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::UNIQUE_NAME);
+  DCHECK(state() == CompareICState::UNIQUE_NAME);
   DCHECK(GetCondition() == eq);
   Label miss;
 
@@ -3454,7 +3458,7 @@ void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateStrings(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::STRING);
+  DCHECK(state() == CompareICState::STRING);
   Label miss;
 
   bool equality = Token::IsEqualityOp(op());
@@ -3533,7 +3537,7 @@ void CompareICStub::GenerateStrings(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateObjects(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::OBJECT);
+  DCHECK(state() == CompareICState::OBJECT);
   Label miss;
   __ and_(r2, r1, Operand(r0));
   __ JumpIfSmi(r2, &miss);
index a6f48a5..1a1c20d 100644 (file)
@@ -12,6 +12,7 @@
 #include "src/compiler.h"
 #include "src/debug.h"
 #include "src/full-codegen.h"
+#include "src/ic/ic.h"
 #include "src/isolate-inl.h"
 #include "src/parser.h"
 #include "src/scopes.h"
@@ -2627,12 +2628,11 @@ void FullCodeGenerator::CallIC(Handle<Code> code,
 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
   Expression* callee = expr->expression();
 
-  CallIC::CallType call_type = callee->IsVariableProxy()
-      ? CallIC::FUNCTION
-      : CallIC::METHOD;
+  CallICState::CallType call_type =
+      callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD;
 
   // Get the target function.
-  if (call_type == CallIC::FUNCTION) {
+  if (call_type == CallICState::FUNCTION) {
     { StackValueContext context(this);
       EmitVariableLoad(callee->AsVariableProxy());
       PrepareForBailout(callee, NO_REGISTERS);
@@ -2676,11 +2676,11 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
   __ push(ip);
   __ str(r0, MemOperand(sp, kPointerSize));
 
-  EmitCall(expr, CallIC::METHOD);
+  EmitCall(expr, CallICState::METHOD);
 }
 
 
-void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
+void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Load the arguments.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
index 5828c1e..3d66ec7 100644 (file)
@@ -10,6 +10,7 @@
 #include "src/code-factory.h"
 #include "src/code-stubs.h"
 #include "src/hydrogen-osr.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
 
 namespace v8 {
index 39fec09..b243fad 100644 (file)
@@ -10,6 +10,7 @@
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
@@ -472,12 +473,12 @@ static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm,
 
 static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input,
                                          Register scratch,
-                                         CompareIC::State expected,
+                                         CompareICState::State expected,
                                          Label* fail) {
   Label ok;
-  if (expected == CompareIC::SMI) {
+  if (expected == CompareICState::SMI) {
     __ JumpIfNotSmi(input, fail);
-  } else if (expected == CompareIC::NUMBER) {
+  } else if (expected == CompareICState::NUMBER) {
     __ JumpIfSmi(input, &ok);
     __ CheckMap(input, scratch, Heap::kHeapNumberMapRootIndex, fail,
                 DONT_DO_SMI_CHECK);
@@ -2953,7 +2954,7 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
   __ TailCallStub(&stub);
 
   __ bind(&miss);
-  GenerateMiss(masm, IC::kCallIC_Customization_Miss);
+  GenerateMiss(masm);
 
   // The slow case, we need this no matter what to complete a call after a miss.
   CallFunctionNoFeedback(masm,
@@ -3037,7 +3038,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
 
   // We are here because tracing is on or we are going monomorphic.
   __ bind(&miss);
-  GenerateMiss(masm, IC::kCallIC_Miss);
+  GenerateMiss(masm);
 
   // the slow case
   __ bind(&slow_start);
@@ -3051,7 +3052,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
 }
 
 
-void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
+void CallICStub::GenerateMiss(MacroAssembler* masm) {
   ASM_LOCATION("CallICStub[Miss]");
 
   // Get the receiver of the function from the stack; 1 ~ return address.
@@ -3064,6 +3065,9 @@ void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
     __ Push(x4, x1, x2, x3);
 
     // Call the entry.
+    IC::UtilityId id = GetICState() == DEFAULT ? IC::kCallIC_Miss
+                                               : IC::kCallIC_Customization_Miss;
+
     ExternalReference miss = ExternalReference(IC_Utility(id),
                                                masm->isolate());
     __ CallExternalReference(miss, 4);
@@ -3191,7 +3195,7 @@ void StringCharFromCodeGenerator::GenerateSlow(
 
 void CompareICStub::GenerateSmis(MacroAssembler* masm) {
   // Inputs are in x0 (lhs) and x1 (rhs).
-  DCHECK(state() == CompareIC::SMI);
+  DCHECK(state() == CompareICState::SMI);
   ASM_LOCATION("CompareICStub[Smis]");
   Label miss;
   // Bail out (to 'miss') unless both x0 and x1 are smis.
@@ -3213,7 +3217,7 @@ void CompareICStub::GenerateSmis(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::NUMBER);
+  DCHECK(state() == CompareICState::NUMBER);
   ASM_LOCATION("CompareICStub[HeapNumbers]");
 
   Label unordered, maybe_undefined1, maybe_undefined2;
@@ -3226,10 +3230,10 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
   FPRegister rhs_d = d0;
   FPRegister lhs_d = d1;
 
-  if (left() == CompareIC::SMI) {
+  if (left() == CompareICState::SMI) {
     __ JumpIfNotSmi(lhs, &miss);
   }
-  if (right() == CompareIC::SMI) {
+  if (right() == CompareICState::SMI) {
     __ JumpIfNotSmi(rhs, &miss);
   }
 
@@ -3258,8 +3262,8 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
   __ Ret();
 
   __ Bind(&unordered);
-  CompareICStub stub(isolate(), op(), CompareIC::GENERIC, CompareIC::GENERIC,
-                     CompareIC::GENERIC);
+  CompareICStub stub(isolate(), op(), CompareICState::GENERIC,
+                     CompareICState::GENERIC, CompareICState::GENERIC);
   __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
 
   __ Bind(&maybe_undefined1);
@@ -3281,7 +3285,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::INTERNALIZED_STRING);
+  DCHECK(state() == CompareICState::INTERNALIZED_STRING);
   ASM_LOCATION("CompareICStub[InternalizedStrings]");
   Label miss;
 
@@ -3319,7 +3323,7 @@ void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::UNIQUE_NAME);
+  DCHECK(state() == CompareICState::UNIQUE_NAME);
   ASM_LOCATION("CompareICStub[UniqueNames]");
   DCHECK(GetCondition() == eq);
   Label miss;
@@ -3358,7 +3362,7 @@ void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateStrings(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::STRING);
+  DCHECK(state() == CompareICState::STRING);
   ASM_LOCATION("CompareICStub[Strings]");
 
   Label miss;
@@ -3439,7 +3443,7 @@ void CompareICStub::GenerateStrings(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateObjects(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::OBJECT);
+  DCHECK(state() == CompareICState::OBJECT);
   ASM_LOCATION("CompareICStub[Objects]");
 
   Label miss;
index 141fc04..8044371 100644 (file)
@@ -12,6 +12,7 @@
 #include "src/compiler.h"
 #include "src/debug.h"
 #include "src/full-codegen.h"
+#include "src/ic/ic.h"
 #include "src/isolate-inl.h"
 #include "src/parser.h"
 #include "src/scopes.h"
@@ -2291,12 +2292,11 @@ void FullCodeGenerator::CallIC(Handle<Code> code,
 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
   Expression* callee = expr->expression();
 
-  CallIC::CallType call_type = callee->IsVariableProxy()
-      ? CallIC::FUNCTION
-      : CallIC::METHOD;
+  CallICState::CallType call_type =
+      callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD;
 
   // Get the target function.
-  if (call_type == CallIC::FUNCTION) {
+  if (call_type == CallICState::FUNCTION) {
     { StackValueContext context(this);
       EmitVariableLoad(callee->AsVariableProxy());
       PrepareForBailout(callee, NO_REGISTERS);
@@ -2338,11 +2338,11 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
   __ Pop(x10);
   __ Push(x0, x10);
 
-  EmitCall(expr, CallIC::METHOD);
+  EmitCall(expr, CallICState::METHOD);
 }
 
 
-void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
+void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Load the arguments.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
index 66f5963..a2127e9 100644 (file)
@@ -10,6 +10,7 @@
 #include "src/code-factory.h"
 #include "src/code-stubs.h"
 #include "src/hydrogen-osr.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
 
 namespace v8 {
index 026804f..a705300 100644 (file)
@@ -46,6 +46,7 @@
 #include "src/debug.h"
 #include "src/deoptimizer.h"
 #include "src/execution.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
 #include "src/isolate-inl.h"
 #include "src/jsregexp.h"
index c9fc862..c969c8f 100644 (file)
@@ -14,7 +14,7 @@ namespace internal {
 // static
 Callable CodeFactory::LoadIC(Isolate* isolate, ContextualMode mode) {
   return Callable(
-      LoadIC::initialize_stub(isolate, LoadIC::State(mode).GetExtraICState()),
+      LoadIC::initialize_stub(isolate, LoadICState(mode).GetExtraICState()),
       LoadDescriptor(isolate));
 }
 
index 57bf1e8..3a9688a 100644 (file)
@@ -905,7 +905,7 @@ Handle<Code> CompareNilICStub::GenerateCode() {
 
 template <>
 HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
-  BinaryOpIC::State state = casted_stub()->state();
+  BinaryOpICState state = casted_stub()->state();
 
   HValue* left = GetParameter(BinaryOpICStub::kLeft);
   HValue* right = GetParameter(BinaryOpICStub::kRight);
@@ -1004,7 +1004,7 @@ Handle<Code> BinaryOpICStub::GenerateCode() {
 
 template <>
 HValue* CodeStubGraphBuilder<BinaryOpWithAllocationSiteStub>::BuildCodeStub() {
-  BinaryOpIC::State state = casted_stub()->state();
+  BinaryOpICState state = casted_stub()->state();
 
   HValue* allocation_site = GetParameter(
       BinaryOpWithAllocationSiteStub::kAllocationSite);
index fac530e..be868ff 100644 (file)
@@ -10,6 +10,7 @@
 #include "src/factory.h"
 #include "src/gdb-jit.h"
 #include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
 #include "src/macro-assembler.h"
 
 namespace v8 {
@@ -258,7 +259,7 @@ void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) {
   }
 
   // Generate special versions of the stub.
-  BinaryOpIC::State::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
+  BinaryOpICState::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
 }
 
 
@@ -269,7 +270,7 @@ void BinaryOpICStub::PrintState(OStream& os) const {  // NOLINT
 
 // static
 void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate,
-                                         const BinaryOpIC::State& state) {
+                                         const BinaryOpICState& state) {
   BinaryOpICStub stub(isolate, state);
   stub.GetCode();
 }
@@ -278,7 +279,7 @@ void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate,
 // static
 void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {
   // Generate special versions of the stub.
-  BinaryOpIC::State::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
+  BinaryOpICState::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
 }
 
 
@@ -290,7 +291,7 @@ void BinaryOpICWithAllocationSiteStub::PrintState(
 
 // static
 void BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(
-    Isolate* isolate, const BinaryOpIC::State& state) {
+    Isolate* isolate, const BinaryOpICState& state) {
   if (state.CouldCreateAllocationMementos()) {
     BinaryOpICWithAllocationSiteStub stub(isolate, state);
     stub.GetCode();
@@ -314,19 +315,19 @@ void StringAddStub::PrintBaseName(OStream& os) const {  // NOLINT
 
 
 InlineCacheState CompareICStub::GetICState() const {
-  CompareIC::State state = Max(left(), right());
+  CompareICState::State state = Max(left(), right());
   switch (state) {
-    case CompareIC::UNINITIALIZED:
+    case CompareICState::UNINITIALIZED:
       return ::v8::internal::UNINITIALIZED;
-    case CompareIC::SMI:
-    case CompareIC::NUMBER:
-    case CompareIC::INTERNALIZED_STRING:
-    case CompareIC::STRING:
-    case CompareIC::UNIQUE_NAME:
-    case CompareIC::OBJECT:
-    case CompareIC::KNOWN_OBJECT:
+    case CompareICState::SMI:
+    case CompareICState::NUMBER:
+    case CompareICState::INTERNALIZED_STRING:
+    case CompareICState::STRING:
+    case CompareICState::UNIQUE_NAME:
+    case CompareICState::OBJECT:
+    case CompareICState::KNOWN_OBJECT:
       return MONOMORPHIC;
-    case CompareIC::GENERIC:
+    case CompareICState::GENERIC:
       return ::v8::internal::GENERIC;
   }
   UNREACHABLE();
@@ -334,6 +335,11 @@ InlineCacheState CompareICStub::GetICState() const {
 }
 
 
+Condition CompareICStub::GetCondition() const {
+  return CompareIC::ComputeCondition(op());
+}
+
+
 void CompareICStub::AddToSpecialCache(Handle<Code> new_object) {
   DCHECK(*known_map_ != NULL);
   Isolate* isolate = new_object->GetIsolate();
@@ -376,32 +382,32 @@ bool CompareICStub::FindCodeInSpecialCache(Code** code_out) {
 
 void CompareICStub::Generate(MacroAssembler* masm) {
   switch (state()) {
-    case CompareIC::UNINITIALIZED:
+    case CompareICState::UNINITIALIZED:
       GenerateMiss(masm);
       break;
-    case CompareIC::SMI:
+    case CompareICState::SMI:
       GenerateSmis(masm);
       break;
-    case CompareIC::NUMBER:
+    case CompareICState::NUMBER:
       GenerateNumbers(masm);
       break;
-    case CompareIC::STRING:
+    case CompareICState::STRING:
       GenerateStrings(masm);
       break;
-    case CompareIC::INTERNALIZED_STRING:
+    case CompareICState::INTERNALIZED_STRING:
       GenerateInternalizedStrings(masm);
       break;
-    case CompareIC::UNIQUE_NAME:
+    case CompareICState::UNIQUE_NAME:
       GenerateUniqueNames(masm);
       break;
-    case CompareIC::OBJECT:
+    case CompareICState::OBJECT:
       GenerateObjects(masm);
       break;
-    case CompareIC::KNOWN_OBJECT:
+    case CompareICState::KNOWN_OBJECT:
       DCHECK(*known_map_ != NULL);
       GenerateKnownObjects(masm);
       break;
-    case CompareIC::GENERIC:
+    case CompareICState::GENERIC:
       GenerateGeneric(masm);
       break;
   }
index eb858b0..08b434e 100644 (file)
@@ -9,7 +9,7 @@
 #include "src/assembler.h"
 #include "src/codegen.h"
 #include "src/globals.h"
-#include "src/ic/ic.h"
+#include "src/ic/ic-state.h"
 #include "src/interface-descriptors.h"
 #include "src/macro-assembler.h"
 #include "src/ostreams.h"
@@ -781,13 +781,13 @@ class MathPowStub: public PlatformCodeStub {
 
 class CallICStub: public PlatformCodeStub {
  public:
-  CallICStub(Isolate* isolate, const CallIC::State& state)
+  CallICStub(Isolate* isolate, const CallICState& state)
       : PlatformCodeStub(isolate) {
     minor_key_ = state.GetExtraICState();
   }
 
   static int ExtractArgcFromMinorKey(int minor_key) {
-    CallIC::State state(static_cast<ExtraICState>(minor_key));
+    CallICState state(static_cast<ExtraICState>(minor_key));
     return state.arg_count();
   }
 
@@ -800,16 +800,18 @@ class CallICStub: public PlatformCodeStub {
   }
 
  protected:
-  bool CallAsMethod() const { return state().call_type() == CallIC::METHOD; }
+  bool CallAsMethod() const {
+    return state().call_type() == CallICState::METHOD;
+  }
 
   int arg_count() const { return state().arg_count(); }
 
-  CallIC::State state() const {
-    return CallIC::State(static_cast<ExtraICState>(minor_key_));
+  CallICState state() const {
+    return CallICState(static_cast<ExtraICState>(minor_key_));
   }
 
   // Code generation helpers.
-  void GenerateMiss(MacroAssembler* masm, IC::UtilityId id);
+  void GenerateMiss(MacroAssembler* masm);
 
  private:
   virtual void PrintState(OStream& os) const OVERRIDE;  // NOLINT
@@ -821,7 +823,7 @@ class CallICStub: public PlatformCodeStub {
 
 class CallIC_ArrayStub: public CallICStub {
  public:
-  CallIC_ArrayStub(Isolate* isolate, const CallIC::State& state_in)
+  CallIC_ArrayStub(Isolate* isolate, const CallICState& state_in)
       : CallICStub(isolate, state_in) {}
 
   virtual InlineCacheState GetICState() const FINAL OVERRIDE {
@@ -1058,11 +1060,11 @@ class BinaryOpICStub : public HydrogenCodeStub {
   BinaryOpICStub(Isolate* isolate, Token::Value op,
                  OverwriteMode mode = NO_OVERWRITE)
       : HydrogenCodeStub(isolate, UNINITIALIZED) {
-    BinaryOpIC::State state(isolate, op, mode);
+    BinaryOpICState state(isolate, op, mode);
     set_sub_minor_key(state.GetExtraICState());
   }
 
-  BinaryOpICStub(Isolate* isolate, const BinaryOpIC::State& state)
+  BinaryOpICStub(Isolate* isolate, const BinaryOpICState& state)
       : HydrogenCodeStub(isolate) {
     set_sub_minor_key(state.GetExtraICState());
   }
@@ -1081,8 +1083,8 @@ class BinaryOpICStub : public HydrogenCodeStub {
     return static_cast<ExtraICState>(sub_minor_key());
   }
 
-  BinaryOpIC::State state() const {
-    return BinaryOpIC::State(isolate(), GetExtraICState());
+  BinaryOpICState state() const {
+    return BinaryOpICState(isolate(), GetExtraICState());
   }
 
   virtual void PrintState(OStream& os) const FINAL OVERRIDE;  // NOLINT
@@ -1093,7 +1095,7 @@ class BinaryOpICStub : public HydrogenCodeStub {
 
  private:
   static void GenerateAheadOfTime(Isolate* isolate,
-                                  const BinaryOpIC::State& state);
+                                  const BinaryOpICState& state);
 
   DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
   DEFINE_HYDROGEN_CODE_STUB(BinaryOpIC, HydrogenCodeStub);
@@ -1105,7 +1107,7 @@ class BinaryOpICStub : public HydrogenCodeStub {
 class BinaryOpICWithAllocationSiteStub FINAL : public PlatformCodeStub {
  public:
   BinaryOpICWithAllocationSiteStub(Isolate* isolate,
-                                   const BinaryOpIC::State& state)
+                                   const BinaryOpICState& state)
       : PlatformCodeStub(isolate) {
     minor_key_ = state.GetExtraICState();
   }
@@ -1133,12 +1135,12 @@ class BinaryOpICWithAllocationSiteStub FINAL : public PlatformCodeStub {
   virtual void PrintState(OStream& os) const OVERRIDE;  // NOLINT
 
  private:
-  BinaryOpIC::State state() const {
-    return BinaryOpIC::State(isolate(), static_cast<ExtraICState>(minor_key_));
+  BinaryOpICState state() const {
+    return BinaryOpICState(isolate(), static_cast<ExtraICState>(minor_key_));
   }
 
   static void GenerateAheadOfTime(Isolate* isolate,
-                                  const BinaryOpIC::State& state);
+                                  const BinaryOpICState& state);
 
   DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite);
   DEFINE_PLATFORM_CODE_STUB(BinaryOpICWithAllocationSite, PlatformCodeStub);
@@ -1152,8 +1154,7 @@ class BinaryOpWithAllocationSiteStub FINAL : public BinaryOpICStub {
                                  OverwriteMode mode)
       : BinaryOpICStub(isolate, op, mode) {}
 
-  BinaryOpWithAllocationSiteStub(Isolate* isolate,
-                                 const BinaryOpIC::State& state)
+  BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state)
       : BinaryOpICStub(isolate, state) {}
 
   virtual Code::Kind GetCodeKind() const FINAL OVERRIDE {
@@ -1216,8 +1217,8 @@ class StringAddStub FINAL : public HydrogenCodeStub {
 
 class CompareICStub : public PlatformCodeStub {
  public:
-  CompareICStub(Isolate* isolate, Token::Value op, CompareIC::State left,
-                CompareIC::State right, CompareIC::State state)
+  CompareICStub(Isolate* isolate, Token::Value op, CompareICState::State left,
+                CompareICState::State right, CompareICState::State state)
       : PlatformCodeStub(isolate) {
     DCHECK(Token::IsCompareOp(op));
     minor_key_ = OpBits::encode(op - Token::EQ) | LeftStateBits::encode(left) |
@@ -1232,9 +1233,13 @@ class CompareICStub : public PlatformCodeStub {
     return static_cast<Token::Value>(Token::EQ + OpBits::decode(minor_key_));
   }
 
-  CompareIC::State left() const { return LeftStateBits::decode(minor_key_); }
-  CompareIC::State right() const { return RightStateBits::decode(minor_key_); }
-  CompareIC::State state() const { return StateBits::decode(minor_key_); }
+  CompareICState::State left() const {
+    return LeftStateBits::decode(minor_key_);
+  }
+  CompareICState::State right() const {
+    return RightStateBits::decode(minor_key_);
+  }
+  CompareICState::State state() const { return StateBits::decode(minor_key_); }
 
  private:
   virtual Code::Kind GetCodeKind() const { return Code::COMPARE_IC; }
@@ -1250,16 +1255,18 @@ class CompareICStub : public PlatformCodeStub {
   void GenerateGeneric(MacroAssembler* masm);
 
   bool strict() const { return op() == Token::EQ_STRICT; }
-  Condition GetCondition() const { return CompareIC::ComputeCondition(op()); }
+  Condition GetCondition() const;
 
   virtual void AddToSpecialCache(Handle<Code> new_object);
   virtual bool FindCodeInSpecialCache(Code** code_out);
-  virtual bool UseSpecialCache() { return state() == CompareIC::KNOWN_OBJECT; }
+  virtual bool UseSpecialCache() {
+    return state() == CompareICState::KNOWN_OBJECT;
+  }
 
   class OpBits : public BitField<int, 0, 3> {};
-  class LeftStateBits : public BitField<CompareIC::State, 3, 4> {};
-  class RightStateBits : public BitField<CompareIC::State, 7, 4> {};
-  class StateBits : public BitField<CompareIC::State, 11, 4> {};
+  class LeftStateBits : public BitField<CompareICState::State, 3, 4> {};
+  class RightStateBits : public BitField<CompareICState::State, 7, 4> {};
+  class StateBits : public BitField<CompareICState::State, 11, 4> {};
 
   Handle<Map> known_map_;
 
@@ -1740,7 +1747,7 @@ class KeyedLoadGenericStub : public HydrogenCodeStub {
 
 class LoadICTrampolineStub : public PlatformCodeStub {
  public:
-  LoadICTrampolineStub(Isolate* isolate, const LoadIC::State& state)
+  LoadICTrampolineStub(Isolate* isolate, const LoadICState& state)
       : PlatformCodeStub(isolate) {
     minor_key_ = state.GetExtraICState();
   }
@@ -1756,8 +1763,8 @@ class LoadICTrampolineStub : public PlatformCodeStub {
   }
 
  private:
-  LoadIC::State state() const {
-    return LoadIC::State(static_cast<ExtraICState>(minor_key_));
+  LoadICState state() const {
+    return LoadICState(static_cast<ExtraICState>(minor_key_));
   }
 
   DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorLoadICTrampoline);
@@ -1768,7 +1775,7 @@ class LoadICTrampolineStub : public PlatformCodeStub {
 class KeyedLoadICTrampolineStub : public LoadICTrampolineStub {
  public:
   explicit KeyedLoadICTrampolineStub(Isolate* isolate)
-      : LoadICTrampolineStub(isolate, LoadIC::State(0)) {}
+      : LoadICTrampolineStub(isolate, LoadICState(0)) {}
 
   virtual Code::Kind GetCodeKind() const OVERRIDE {
     return Code::KEYED_LOAD_IC;
@@ -1780,7 +1787,7 @@ class KeyedLoadICTrampolineStub : public LoadICTrampolineStub {
 
 class MegamorphicLoadStub : public HydrogenCodeStub {
  public:
-  MegamorphicLoadStub(Isolate* isolate, const LoadIC::State& state)
+  MegamorphicLoadStub(Isolate* isolate, const LoadICState& state)
       : HydrogenCodeStub(isolate) {
     set_sub_minor_key(state.GetExtraICState());
   }
@@ -1802,7 +1809,7 @@ class MegamorphicLoadStub : public HydrogenCodeStub {
 
 class VectorLoadStub : public HydrogenCodeStub {
  public:
-  explicit VectorLoadStub(Isolate* isolate, const LoadIC::State& state)
+  explicit VectorLoadStub(Isolate* isolate, const LoadICState& state)
       : HydrogenCodeStub(isolate) {
     set_sub_minor_key(state.GetExtraICState());
   }
@@ -1818,7 +1825,7 @@ class VectorLoadStub : public HydrogenCodeStub {
   }
 
  private:
-  LoadIC::State state() const { return LoadIC::State(GetExtraICState()); }
+  LoadICState state() const { return LoadICState(GetExtraICState()); }
 
   DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorLoadIC);
   DEFINE_HYDROGEN_CODE_STUB(VectorLoad, HydrogenCodeStub);
@@ -1828,7 +1835,7 @@ class VectorLoadStub : public HydrogenCodeStub {
 class VectorKeyedLoadStub : public VectorLoadStub {
  public:
   explicit VectorKeyedLoadStub(Isolate* isolate)
-      : VectorLoadStub(isolate, LoadIC::State(0)) {}
+      : VectorLoadStub(isolate, LoadICState(0)) {}
 
   virtual Code::Kind GetCodeKind() const OVERRIDE {
     return Code::KEYED_LOAD_IC;
index 942b2be..d9448ce 100644 (file)
@@ -214,7 +214,8 @@ static int DecodeIt(Isolate* isolate,
         Code::Kind kind = code->kind();
         if (code->is_inline_cache_stub()) {
           if (kind == Code::LOAD_IC &&
-              LoadIC::GetContextualMode(code->extra_ic_state()) == CONTEXTUAL) {
+              LoadICState::GetContextualMode(code->extra_ic_state()) ==
+                  CONTEXTUAL) {
             out.AddFormatted(" contextual,");
           }
           InlineCacheState ic_state = code->ic_state();
index 6814946..605380f 100644 (file)
@@ -475,7 +475,7 @@ class FullCodeGenerator: public AstVisitor {
   void EmitReturnSequence();
 
   // Platform-specific code sequences for calls
-  void EmitCall(Call* expr, CallIC::CallType = CallIC::FUNCTION);
+  void EmitCall(Call* expr, CallICState::CallType = CallICState::FUNCTION);
   void EmitCallWithLoadIC(Call* expr);
   void EmitKeyedCallWithLoadIC(Call* expr, Expression* key);
 
index ce15038..4308412 100644 (file)
@@ -20,6 +20,7 @@
 #include "src/heap/spaces-inl.h"
 #include "src/heap/sweeper-thread.h"
 #include "src/heap-profiler.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
 
 namespace v8 {
index 7fe6a50..d220118 100644 (file)
@@ -266,7 +266,8 @@ void StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget(Heap* heap,
        heap->isolate()->serializer_enabled() ||
        target->ic_age() != heap->global_ic_age() ||
        target->is_invalidated_weak_stub())) {
-    IC::Clear(heap->isolate(), rinfo->pc(), rinfo->host()->constant_pool());
+    ICUtility::Clear(heap->isolate(), rinfo->pc(),
+                     rinfo->host()->constant_pool());
     target = Code::GetCodeFromTargetAddress(rinfo->target_address());
   }
   heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
index 4af1d2b..c5f8dc1 100644 (file)
@@ -35,6 +35,7 @@
 #include "src/hydrogen-store-elimination.h"
 #include "src/hydrogen-uint32-analysis.h"
 #include "src/ic/call-optimization.h"
+#include "src/ic/ic.h"
 // GetRootConstructor
 #include "src/ic/ic-inl.h"
 #include "src/lithium-allocator.h"
@@ -4510,6 +4511,11 @@ void HOptimizedGraphBuilder::SetUpScope(Scope* scope) {
 }
 
 
+Type* HOptimizedGraphBuilder::ToType(Handle<Map> map) {
+  return IC::MapToType<Type>(map, zone());
+}
+
+
 void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) {
   for (int i = 0; i < statements->length(); i++) {
     Statement* stmt = statements->at(i);
@@ -6392,8 +6398,8 @@ static bool ComputeReceiverTypes(Expression* expr,
     types->FilterForPossibleTransitions(root_map);
     monomorphic = types->length() == 1;
   }
-  return monomorphic && CanInlinePropertyAccess(
-      IC::MapToType<Type>(types->first(), zone));
+  return monomorphic &&
+         CanInlinePropertyAccess(IC::MapToType<Type>(types->first(), zone));
 }
 
 
index 265987d..35a53f1 100644 (file)
@@ -2319,7 +2319,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
   AST_NODE_LIST(DECLARE_VISIT)
 #undef DECLARE_VISIT
 
-  Type* ToType(Handle<Map> map) { return IC::MapToType<Type>(map, zone()); }
+  Type* ToType(Handle<Map> map);
 
  private:
   // Helpers for flow graph construction.
index ef507b5..71c974e 100644 (file)
@@ -11,6 +11,7 @@
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
@@ -1525,14 +1526,12 @@ static int NegativeComparisonResult(Condition cc) {
 }
 
 
-static void CheckInputType(MacroAssembler* masm,
-                           Register input,
-                           CompareIC::State expected,
-                           Label* fail) {
+static void CheckInputType(MacroAssembler* masm, Register input,
+                           CompareICState::State expected, Label* fail) {
   Label ok;
-  if (expected == CompareIC::SMI) {
+  if (expected == CompareICState::SMI) {
     __ JumpIfNotSmi(input, fail);
-  } else if (expected == CompareIC::NUMBER) {
+  } else if (expected == CompareICState::NUMBER) {
     __ JumpIfSmi(input, &ok);
     __ cmp(FieldOperand(input, HeapObject::kMapOffset),
            Immediate(masm->isolate()->factory()->heap_number_map()));
@@ -2137,7 +2136,7 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
   __ TailCallStub(&stub);
 
   __ bind(&miss);
-  GenerateMiss(masm, IC::kCallIC_Customization_Miss);
+  GenerateMiss(masm);
 
   // The slow case, we need this no matter what to complete a call after a miss.
   CallFunctionNoFeedback(masm,
@@ -2216,7 +2215,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
 
   // We are here because tracing is on or we are going monomorphic.
   __ bind(&miss);
-  GenerateMiss(masm, IC::kCallIC_Miss);
+  GenerateMiss(masm);
 
   // the slow case
   __ bind(&slow_start);
@@ -2234,7 +2233,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
 }
 
 
-void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
+void CallICStub::GenerateMiss(MacroAssembler* masm) {
   // Get the receiver of the function from the stack; 1 ~ return address.
   __ mov(ecx, Operand(esp, (arg_count() + 1) * kPointerSize));
 
@@ -2248,6 +2247,9 @@ void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
     __ push(edx);
 
     // Call the entry.
+    IC::UtilityId id = GetICState() == DEFAULT ? IC::kCallIC_Miss
+                                               : IC::kCallIC_Customization_Miss;
+
     ExternalReference miss = ExternalReference(IC_Utility(id),
                                                masm->isolate());
     __ CallExternalReference(miss, 4);
@@ -3294,7 +3296,7 @@ void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateSmis(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::SMI);
+  DCHECK(state() == CompareICState::SMI);
   Label miss;
   __ mov(ecx, edx);
   __ or_(ecx, eax);
@@ -3320,16 +3322,16 @@ void CompareICStub::GenerateSmis(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::NUMBER);
+  DCHECK(state() == CompareICState::NUMBER);
 
   Label generic_stub;
   Label unordered, maybe_undefined1, maybe_undefined2;
   Label miss;
 
-  if (left() == CompareIC::SMI) {
+  if (left() == CompareICState::SMI) {
     __ JumpIfNotSmi(edx, &miss);
   }
-  if (right() == CompareIC::SMI) {
+  if (right() == CompareICState::SMI) {
     __ JumpIfNotSmi(eax, &miss);
   }
 
@@ -3376,8 +3378,8 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
 
   __ bind(&unordered);
   __ bind(&generic_stub);
-  CompareICStub stub(isolate(), op(), CompareIC::GENERIC, CompareIC::GENERIC,
-                     CompareIC::GENERIC);
+  CompareICStub stub(isolate(), op(), CompareICState::GENERIC,
+                     CompareICState::GENERIC, CompareICState::GENERIC);
   __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
 
   __ bind(&maybe_undefined1);
@@ -3402,7 +3404,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::INTERNALIZED_STRING);
+  DCHECK(state() == CompareICState::INTERNALIZED_STRING);
   DCHECK(GetCondition() == equal);
 
   // Registers containing left and right operands respectively.
@@ -3447,7 +3449,7 @@ void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::UNIQUE_NAME);
+  DCHECK(state() == CompareICState::UNIQUE_NAME);
   DCHECK(GetCondition() == equal);
 
   // Registers containing left and right operands respectively.
@@ -3492,7 +3494,7 @@ void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateStrings(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::STRING);
+  DCHECK(state() == CompareICState::STRING);
   Label miss;
 
   bool equality = Token::IsEqualityOp(op());
@@ -3582,7 +3584,7 @@ void CompareICStub::GenerateStrings(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateObjects(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::OBJECT);
+  DCHECK(state() == CompareICState::OBJECT);
   Label miss;
   __ mov(ecx, edx);
   __ and_(ecx, eax);
index 6b687e5..96d96a3 100644 (file)
@@ -12,6 +12,7 @@
 #include "src/compiler.h"
 #include "src/debug.h"
 #include "src/full-codegen.h"
+#include "src/ic/ic.h"
 #include "src/isolate-inl.h"
 #include "src/parser.h"
 #include "src/scopes.h"
@@ -2546,11 +2547,10 @@ void FullCodeGenerator::CallIC(Handle<Code> code,
 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
   Expression* callee = expr->expression();
 
-  CallIC::CallType call_type = callee->IsVariableProxy()
-      ? CallIC::FUNCTION
-      : CallIC::METHOD;
+  CallICState::CallType call_type =
+      callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD;
   // Get the target function.
-  if (call_type == CallIC::FUNCTION) {
+  if (call_type == CallICState::FUNCTION) {
     { StackValueContext context(this);
       EmitVariableLoad(callee->AsVariableProxy());
       PrepareForBailout(callee, NO_REGISTERS);
@@ -2592,11 +2592,11 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
   __ push(Operand(esp, 0));
   __ mov(Operand(esp, kPointerSize), eax);
 
-  EmitCall(expr, CallIC::METHOD);
+  EmitCall(expr, CallICState::METHOD);
 }
 
 
-void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
+void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Load the arguments.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
index 2291e64..e0f8d3b 100644 (file)
@@ -13,6 +13,7 @@
 #include "src/deoptimizer.h"
 #include "src/hydrogen-osr.h"
 #include "src/ia32/lithium-codegen-ia32.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
 
 namespace v8 {
index e49abf2..5314d48 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "src/ic/call-optimization.h"
 #include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
 
 namespace v8 {
 namespace internal {
index c9ce6e3..e918fdc 100644 (file)
@@ -6,6 +6,7 @@
 
 #if V8_TARGET_ARCH_ARM
 
+#include "src/ic/ic.h"
 #include "src/ic/ic-compiler.h"
 
 namespace v8 {
index c9eaa9d..f7f82bc 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "src/ic/call-optimization.h"
 #include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
 
 namespace v8 {
 namespace internal {
index f7e1036..fd9a4db 100644 (file)
@@ -6,6 +6,7 @@
 
 #if V8_TARGET_ARCH_ARM64
 
+#include "src/ic/ic.h"
 #include "src/ic/ic-compiler.h"
 
 namespace v8 {
index dd5a067..4219d2b 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "src/ic/call-optimization.h"
 #include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
 #include "src/ic/ic-inl.h"
 
 namespace v8 {
@@ -78,6 +79,11 @@ Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind,
 }
 
 
+void PropertyHandlerCompiler::set_type_for_object(Handle<Object> object) {
+  type_ = IC::CurrentTypeOf(object, isolate());
+}
+
+
 #define __ ACCESS_MASM(masm())
 
 
index 04493e4..f033f3f 100644 (file)
@@ -6,6 +6,7 @@
 #define V8_IC_HANDLER_COMPILER_H_
 
 #include "src/ic/access-compiler.h"
+#include "src/ic/ic-state.h"
 
 namespace v8 {
 namespace internal {
@@ -85,9 +86,7 @@ class PropertyHandlerCompiler : public PropertyAccessCompiler {
                            PrototypeCheckType check = CHECK_ALL_MAPS);
 
   Handle<Code> GetCode(Code::Kind kind, Code::StubType type, Handle<Name> name);
-  void set_type_for_object(Handle<Object> object) {
-    type_ = IC::CurrentTypeOf(object, isolate());
-  }
+  void set_type_for_object(Handle<Object> object);
   void set_holder(Handle<JSObject> holder) { holder_ = holder; }
   Handle<HeapType> type() const { return type_; }
   Handle<JSObject> holder() const { return holder_; }
index 815a5d0..fd97154 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "src/ic/call-optimization.h"
 #include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
 
 namespace v8 {
 namespace internal {
index 2f3c58b..685eac9 100644 (file)
@@ -6,6 +6,7 @@
 
 #if V8_TARGET_ARCH_IA32
 
+#include "src/ic/ic.h"
 #include "src/ic/ic-compiler.h"
 
 namespace v8 {
index f984cee..fc65ac7 100644 (file)
@@ -129,8 +129,8 @@ void IC::set_target(Code* code) {
 
 void LoadIC::set_target(Code* code) {
   // The contextual mode must be preserved across IC patching.
-  DCHECK(GetContextualMode(code->extra_ic_state()) ==
-         GetContextualMode(target()->extra_ic_state()));
+  DCHECK(LoadICState::GetContextualMode(code->extra_ic_state()) ==
+         LoadICState::GetContextualMode(target()->extra_ic_state()));
 
   IC::set_target(code);
 }
diff --git a/src/ic/ic-state.cc b/src/ic/ic-state.cc
new file mode 100644 (file)
index 0000000..4238a72
--- /dev/null
@@ -0,0 +1,614 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/ic/ic.h"
+#include "src/ic/ic-state.h"
+
+namespace v8 {
+namespace internal {
+
+void ICUtility::Clear(Isolate* isolate, Address address,
+                      ConstantPoolArray* constant_pool) {
+  IC::Clear(isolate, address, constant_pool);
+}
+
+
+CallICState::CallICState(ExtraICState extra_ic_state)
+    : argc_(ArgcBits::decode(extra_ic_state)),
+      call_type_(CallTypeBits::decode(extra_ic_state)) {}
+
+
+ExtraICState CallICState::GetExtraICState() const {
+  ExtraICState extra_ic_state =
+      ArgcBits::encode(argc_) | CallTypeBits::encode(call_type_);
+  return extra_ic_state;
+}
+
+
+OStream& operator<<(OStream& os, const CallICState& s) {
+  return os << "(args(" << s.arg_count() << "), "
+            << (s.call_type() == CallICState::METHOD ? "METHOD" : "FUNCTION")
+            << ", ";
+}
+
+
+BinaryOpICState::BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state)
+    : isolate_(isolate) {
+  op_ =
+      static_cast<Token::Value>(FIRST_TOKEN + OpField::decode(extra_ic_state));
+  mode_ = OverwriteModeField::decode(extra_ic_state);
+  fixed_right_arg_ =
+      Maybe<int>(HasFixedRightArgField::decode(extra_ic_state),
+                 1 << FixedRightArgValueField::decode(extra_ic_state));
+  left_kind_ = LeftKindField::decode(extra_ic_state);
+  if (fixed_right_arg_.has_value) {
+    right_kind_ = Smi::IsValid(fixed_right_arg_.value) ? SMI : INT32;
+  } else {
+    right_kind_ = RightKindField::decode(extra_ic_state);
+  }
+  result_kind_ = ResultKindField::decode(extra_ic_state);
+  DCHECK_LE(FIRST_TOKEN, op_);
+  DCHECK_LE(op_, LAST_TOKEN);
+}
+
+
+ExtraICState BinaryOpICState::GetExtraICState() const {
+  ExtraICState extra_ic_state =
+      OpField::encode(op_ - FIRST_TOKEN) | OverwriteModeField::encode(mode_) |
+      LeftKindField::encode(left_kind_) |
+      ResultKindField::encode(result_kind_) |
+      HasFixedRightArgField::encode(fixed_right_arg_.has_value);
+  if (fixed_right_arg_.has_value) {
+    extra_ic_state = FixedRightArgValueField::update(
+        extra_ic_state, WhichPowerOf2(fixed_right_arg_.value));
+  } else {
+    extra_ic_state = RightKindField::update(extra_ic_state, right_kind_);
+  }
+  return extra_ic_state;
+}
+
+
+// static
+void BinaryOpICState::GenerateAheadOfTime(
+    Isolate* isolate, void (*Generate)(Isolate*, const BinaryOpICState&)) {
+// TODO(olivf) We should investigate why adding stubs to the snapshot is so
+// expensive at runtime. When solved we should be able to add most binops to
+// the snapshot instead of hand-picking them.
+// Generated list of commonly used stubs
+#define GENERATE(op, left_kind, right_kind, result_kind, mode) \
+  do {                                                         \
+    BinaryOpICState state(isolate, op, mode);                  \
+    state.left_kind_ = left_kind;                              \
+    state.fixed_right_arg_.has_value = false;                  \
+    state.right_kind_ = right_kind;                            \
+    state.result_kind_ = result_kind;                          \
+    Generate(isolate, state);                                  \
+  } while (false)
+  GENERATE(Token::ADD, INT32, INT32, INT32, NO_OVERWRITE);
+  GENERATE(Token::ADD, INT32, INT32, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::ADD, INT32, INT32, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::ADD, INT32, INT32, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::ADD, INT32, NUMBER, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::ADD, INT32, SMI, INT32, NO_OVERWRITE);
+  GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::ADD, NUMBER, INT32, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::ADD, NUMBER, SMI, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::ADD, SMI, INT32, INT32, NO_OVERWRITE);
+  GENERATE(Token::ADD, SMI, INT32, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::ADD, SMI, INT32, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::ADD, SMI, NUMBER, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE);
+  GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_AND, INT32, INT32, SMI, NO_OVERWRITE);
+  GENERATE(Token::BIT_AND, INT32, INT32, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_AND, INT32, SMI, INT32, NO_OVERWRITE);
+  GENERATE(Token::BIT_AND, INT32, SMI, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_AND, INT32, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_AND, NUMBER, INT32, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_AND, SMI, INT32, INT32, NO_OVERWRITE);
+  GENERATE(Token::BIT_AND, SMI, INT32, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_AND, SMI, NUMBER, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_AND, SMI, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_OR, INT32, INT32, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_OR, INT32, SMI, INT32, NO_OVERWRITE);
+  GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_OR, INT32, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::BIT_OR, INT32, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, NO_OVERWRITE);
+  GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_OR, SMI, INT32, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_XOR, INT32, INT32, INT32, NO_OVERWRITE);
+  GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_XOR, INT32, INT32, SMI, NO_OVERWRITE);
+  GENERATE(Token::BIT_XOR, INT32, INT32, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_XOR, INT32, NUMBER, SMI, NO_OVERWRITE);
+  GENERATE(Token::BIT_XOR, INT32, SMI, INT32, NO_OVERWRITE);
+  GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::BIT_XOR, NUMBER, INT32, INT32, NO_OVERWRITE);
+  GENERATE(Token::BIT_XOR, NUMBER, SMI, INT32, NO_OVERWRITE);
+  GENERATE(Token::BIT_XOR, NUMBER, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::BIT_XOR, SMI, INT32, INT32, NO_OVERWRITE);
+  GENERATE(Token::BIT_XOR, SMI, INT32, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_XOR, SMI, INT32, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_XOR, SMI, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::DIV, INT32, INT32, INT32, NO_OVERWRITE);
+  GENERATE(Token::DIV, INT32, INT32, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::DIV, INT32, NUMBER, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::DIV, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::DIV, INT32, SMI, INT32, NO_OVERWRITE);
+  GENERATE(Token::DIV, INT32, SMI, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::DIV, NUMBER, INT32, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::DIV, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::DIV, NUMBER, SMI, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::DIV, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::DIV, SMI, INT32, INT32, NO_OVERWRITE);
+  GENERATE(Token::DIV, SMI, INT32, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::DIV, SMI, INT32, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::DIV, SMI, NUMBER, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::DIV, SMI, SMI, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::DIV, SMI, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::MOD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::MOD, SMI, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::MOD, SMI, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::MUL, INT32, INT32, INT32, NO_OVERWRITE);
+  GENERATE(Token::MUL, INT32, INT32, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::MUL, INT32, NUMBER, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::MUL, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::MUL, INT32, SMI, INT32, NO_OVERWRITE);
+  GENERATE(Token::MUL, INT32, SMI, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::MUL, INT32, SMI, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::MUL, NUMBER, INT32, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::MUL, NUMBER, SMI, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::MUL, SMI, INT32, INT32, NO_OVERWRITE);
+  GENERATE(Token::MUL, SMI, INT32, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::MUL, SMI, INT32, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::MUL, SMI, NUMBER, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::MUL, SMI, SMI, INT32, NO_OVERWRITE);
+  GENERATE(Token::MUL, SMI, SMI, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::MUL, SMI, SMI, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::MUL, SMI, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::SAR, INT32, SMI, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::SAR, INT32, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::SAR, INT32, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::SAR, NUMBER, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::SAR, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::SHL, INT32, SMI, INT32, NO_OVERWRITE);
+  GENERATE(Token::SHL, INT32, SMI, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::SHL, INT32, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::SHL, INT32, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::SHL, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::SHL, SMI, SMI, INT32, NO_OVERWRITE);
+  GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::SHL, SMI, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::SHR, INT32, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::SHR, NUMBER, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::SHR, NUMBER, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::SHR, NUMBER, SMI, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::SHR, SMI, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::SUB, INT32, INT32, INT32, NO_OVERWRITE);
+  GENERATE(Token::SUB, INT32, INT32, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::SUB, INT32, NUMBER, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::SUB, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_LEFT);
+  GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_RIGHT);
+  GENERATE(Token::SUB, NUMBER, INT32, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::SUB, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::SUB, NUMBER, SMI, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::SUB, SMI, INT32, INT32, NO_OVERWRITE);
+  GENERATE(Token::SUB, SMI, NUMBER, NUMBER, NO_OVERWRITE);
+  GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
+  GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
+  GENERATE(Token::SUB, SMI, SMI, SMI, NO_OVERWRITE);
+  GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_RIGHT);
+#undef GENERATE
+#define GENERATE(op, left_kind, fixed_right_arg_value, result_kind, mode) \
+  do {                                                                    \
+    BinaryOpICState state(isolate, op, mode);                             \
+    state.left_kind_ = left_kind;                                         \
+    state.fixed_right_arg_.has_value = true;                              \
+    state.fixed_right_arg_.value = fixed_right_arg_value;                 \
+    state.right_kind_ = SMI;                                              \
+    state.result_kind_ = result_kind;                                     \
+    Generate(isolate, state);                                             \
+  } while (false)
+  GENERATE(Token::MOD, SMI, 2, SMI, NO_OVERWRITE);
+  GENERATE(Token::MOD, SMI, 4, SMI, NO_OVERWRITE);
+  GENERATE(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::MOD, SMI, 8, SMI, NO_OVERWRITE);
+  GENERATE(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT);
+  GENERATE(Token::MOD, SMI, 32, SMI, NO_OVERWRITE);
+  GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE);
+#undef GENERATE
+}
+
+
+Type* BinaryOpICState::GetResultType(Zone* zone) const {
+  Kind result_kind = result_kind_;
+  if (HasSideEffects()) {
+    result_kind = NONE;
+  } else if (result_kind == GENERIC && op_ == Token::ADD) {
+    return Type::Union(Type::Number(zone), Type::String(zone), zone);
+  } else if (result_kind == NUMBER && op_ == Token::SHR) {
+    return Type::Unsigned32(zone);
+  }
+  DCHECK_NE(GENERIC, result_kind);
+  return KindToType(result_kind, zone);
+}
+
+
+OStream& operator<<(OStream& os, const BinaryOpICState& s) {
+  os << "(" << Token::Name(s.op_);
+  if (s.mode_ == OVERWRITE_LEFT)
+    os << "_ReuseLeft";
+  else if (s.mode_ == OVERWRITE_RIGHT)
+    os << "_ReuseRight";
+  if (s.CouldCreateAllocationMementos()) os << "_CreateAllocationMementos";
+  os << ":" << BinaryOpICState::KindToString(s.left_kind_) << "*";
+  if (s.fixed_right_arg_.has_value) {
+    os << s.fixed_right_arg_.value;
+  } else {
+    os << BinaryOpICState::KindToString(s.right_kind_);
+  }
+  return os << "->" << BinaryOpICState::KindToString(s.result_kind_) << ")";
+}
+
+
+void BinaryOpICState::Update(Handle<Object> left, Handle<Object> right,
+                             Handle<Object> result) {
+  ExtraICState old_extra_ic_state = GetExtraICState();
+
+  left_kind_ = UpdateKind(left, left_kind_);
+  right_kind_ = UpdateKind(right, right_kind_);
+
+  int32_t fixed_right_arg_value = 0;
+  bool has_fixed_right_arg =
+      op_ == Token::MOD && right->ToInt32(&fixed_right_arg_value) &&
+      fixed_right_arg_value > 0 &&
+      base::bits::IsPowerOfTwo32(fixed_right_arg_value) &&
+      FixedRightArgValueField::is_valid(WhichPowerOf2(fixed_right_arg_value)) &&
+      (left_kind_ == SMI || left_kind_ == INT32) &&
+      (result_kind_ == NONE || !fixed_right_arg_.has_value);
+  fixed_right_arg_ = Maybe<int32_t>(has_fixed_right_arg, fixed_right_arg_value);
+
+  result_kind_ = UpdateKind(result, result_kind_);
+
+  if (!Token::IsTruncatingBinaryOp(op_)) {
+    Kind input_kind = Max(left_kind_, right_kind_);
+    if (result_kind_ < input_kind && input_kind <= NUMBER) {
+      result_kind_ = input_kind;
+    }
+  }
+
+  // We don't want to distinguish INT32 and NUMBER for string add (because
+  // NumberToString can't make use of this anyway).
+  if (left_kind_ == STRING && right_kind_ == INT32) {
+    DCHECK_EQ(STRING, result_kind_);
+    DCHECK_EQ(Token::ADD, op_);
+    right_kind_ = NUMBER;
+  } else if (right_kind_ == STRING && left_kind_ == INT32) {
+    DCHECK_EQ(STRING, result_kind_);
+    DCHECK_EQ(Token::ADD, op_);
+    left_kind_ = NUMBER;
+  }
+
+  // Reset overwrite mode unless we can actually make use of it, or may be able
+  // to make use of it at some point in the future.
+  if ((mode_ == OVERWRITE_LEFT && left_kind_ > NUMBER) ||
+      (mode_ == OVERWRITE_RIGHT && right_kind_ > NUMBER) ||
+      result_kind_ > NUMBER) {
+    mode_ = NO_OVERWRITE;
+  }
+
+  if (old_extra_ic_state == GetExtraICState()) {
+    // Tagged operations can lead to non-truncating HChanges
+    if (left->IsUndefined() || left->IsBoolean()) {
+      left_kind_ = GENERIC;
+    } else {
+      DCHECK(right->IsUndefined() || right->IsBoolean());
+      right_kind_ = GENERIC;
+    }
+  }
+}
+
+
+BinaryOpICState::Kind BinaryOpICState::UpdateKind(Handle<Object> object,
+                                                  Kind kind) const {
+  Kind new_kind = GENERIC;
+  bool is_truncating = Token::IsTruncatingBinaryOp(op());
+  if (object->IsBoolean() && is_truncating) {
+    // Booleans will be automatically truncated by HChange.
+    new_kind = INT32;
+  } else if (object->IsUndefined()) {
+    // Undefined will be automatically truncated by HChange.
+    new_kind = is_truncating ? INT32 : NUMBER;
+  } else if (object->IsSmi()) {
+    new_kind = SMI;
+  } else if (object->IsHeapNumber()) {
+    double value = Handle<HeapNumber>::cast(object)->value();
+    new_kind = IsInt32Double(value) ? INT32 : NUMBER;
+  } else if (object->IsString() && op() == Token::ADD) {
+    new_kind = STRING;
+  }
+  if (new_kind == INT32 && SmiValuesAre32Bits()) {
+    new_kind = NUMBER;
+  }
+  if (kind != NONE && ((new_kind <= NUMBER && kind > NUMBER) ||
+                       (new_kind > NUMBER && kind <= NUMBER))) {
+    new_kind = GENERIC;
+  }
+  return Max(kind, new_kind);
+}
+
+
+// static
+const char* BinaryOpICState::KindToString(Kind kind) {
+  switch (kind) {
+    case NONE:
+      return "None";
+    case SMI:
+      return "Smi";
+    case INT32:
+      return "Int32";
+    case NUMBER:
+      return "Number";
+    case STRING:
+      return "String";
+    case GENERIC:
+      return "Generic";
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+
+// static
+Type* BinaryOpICState::KindToType(Kind kind, Zone* zone) {
+  switch (kind) {
+    case NONE:
+      return Type::None(zone);
+    case SMI:
+      return Type::SignedSmall(zone);
+    case INT32:
+      return Type::Signed32(zone);
+    case NUMBER:
+      return Type::Number(zone);
+    case STRING:
+      return Type::String(zone);
+    case GENERIC:
+      return Type::Any(zone);
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+
+const char* CompareICState::GetStateName(State state) {
+  switch (state) {
+    case UNINITIALIZED:
+      return "UNINITIALIZED";
+    case SMI:
+      return "SMI";
+    case NUMBER:
+      return "NUMBER";
+    case INTERNALIZED_STRING:
+      return "INTERNALIZED_STRING";
+    case STRING:
+      return "STRING";
+    case UNIQUE_NAME:
+      return "UNIQUE_NAME";
+    case OBJECT:
+      return "OBJECT";
+    case KNOWN_OBJECT:
+      return "KNOWN_OBJECT";
+    case GENERIC:
+      return "GENERIC";
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+
+Type* CompareICState::StateToType(Zone* zone, State state, Handle<Map> map) {
+  switch (state) {
+    case UNINITIALIZED:
+      return Type::None(zone);
+    case SMI:
+      return Type::SignedSmall(zone);
+    case NUMBER:
+      return Type::Number(zone);
+    case STRING:
+      return Type::String(zone);
+    case INTERNALIZED_STRING:
+      return Type::InternalizedString(zone);
+    case UNIQUE_NAME:
+      return Type::UniqueName(zone);
+    case OBJECT:
+      return Type::Receiver(zone);
+    case KNOWN_OBJECT:
+      return map.is_null() ? Type::Receiver(zone) : Type::Class(map, zone);
+    case GENERIC:
+      return Type::Any(zone);
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+
+CompareICState::State CompareICState::NewInputState(State old_state,
+                                                    Handle<Object> value) {
+  switch (old_state) {
+    case UNINITIALIZED:
+      if (value->IsSmi()) return SMI;
+      if (value->IsHeapNumber()) return NUMBER;
+      if (value->IsInternalizedString()) return INTERNALIZED_STRING;
+      if (value->IsString()) return STRING;
+      if (value->IsSymbol()) return UNIQUE_NAME;
+      if (value->IsJSObject()) return OBJECT;
+      break;
+    case SMI:
+      if (value->IsSmi()) return SMI;
+      if (value->IsHeapNumber()) return NUMBER;
+      break;
+    case NUMBER:
+      if (value->IsNumber()) return NUMBER;
+      break;
+    case INTERNALIZED_STRING:
+      if (value->IsInternalizedString()) return INTERNALIZED_STRING;
+      if (value->IsString()) return STRING;
+      if (value->IsSymbol()) return UNIQUE_NAME;
+      break;
+    case STRING:
+      if (value->IsString()) return STRING;
+      break;
+    case UNIQUE_NAME:
+      if (value->IsUniqueName()) return UNIQUE_NAME;
+      break;
+    case OBJECT:
+      if (value->IsJSObject()) return OBJECT;
+      break;
+    case GENERIC:
+      break;
+    case KNOWN_OBJECT:
+      UNREACHABLE();
+      break;
+  }
+  return GENERIC;
+}
+
+
+// static
+CompareICState::State CompareICState::TargetState(
+    State old_state, State old_left, State old_right, Token::Value op,
+    bool has_inlined_smi_code, Handle<Object> x, Handle<Object> y) {
+  switch (old_state) {
+    case UNINITIALIZED:
+      if (x->IsSmi() && y->IsSmi()) return SMI;
+      if (x->IsNumber() && y->IsNumber()) return NUMBER;
+      if (Token::IsOrderedRelationalCompareOp(op)) {
+        // Ordered comparisons treat undefined as NaN, so the
+        // NUMBER stub will do the right thing.
+        if ((x->IsNumber() && y->IsUndefined()) ||
+            (y->IsNumber() && x->IsUndefined())) {
+          return NUMBER;
+        }
+      }
+      if (x->IsInternalizedString() && y->IsInternalizedString()) {
+        // We compare internalized strings as plain ones if we need to determine
+        // the order in a non-equality compare.
+        return Token::IsEqualityOp(op) ? INTERNALIZED_STRING : STRING;
+      }
+      if (x->IsString() && y->IsString()) return STRING;
+      if (!Token::IsEqualityOp(op)) return GENERIC;
+      if (x->IsUniqueName() && y->IsUniqueName()) return UNIQUE_NAME;
+      if (x->IsJSObject() && y->IsJSObject()) {
+        if (Handle<JSObject>::cast(x)->map() ==
+            Handle<JSObject>::cast(y)->map()) {
+          return KNOWN_OBJECT;
+        } else {
+          return OBJECT;
+        }
+      }
+      return GENERIC;
+    case SMI:
+      return x->IsNumber() && y->IsNumber() ? NUMBER : GENERIC;
+    case INTERNALIZED_STRING:
+      DCHECK(Token::IsEqualityOp(op));
+      if (x->IsString() && y->IsString()) return STRING;
+      if (x->IsUniqueName() && y->IsUniqueName()) return UNIQUE_NAME;
+      return GENERIC;
+    case NUMBER:
+      // If the failure was due to one side changing from smi to heap number,
+      // then keep the state (if other changed at the same time, we will get
+      // a second miss and then go to generic).
+      if (old_left == SMI && x->IsHeapNumber()) return NUMBER;
+      if (old_right == SMI && y->IsHeapNumber()) return NUMBER;
+      return GENERIC;
+    case KNOWN_OBJECT:
+      DCHECK(Token::IsEqualityOp(op));
+      if (x->IsJSObject() && y->IsJSObject()) {
+        return OBJECT;
+      }
+      return GENERIC;
+    case STRING:
+    case UNIQUE_NAME:
+    case OBJECT:
+    case GENERIC:
+      return GENERIC;
+  }
+  UNREACHABLE();
+  return GENERIC;  // Make the compiler happy.
+}
+}
+}  // namespace v8::internal
diff --git a/src/ic/ic-state.h b/src/ic/ic-state.h
new file mode 100644 (file)
index 0000000..b84bdb9
--- /dev/null
@@ -0,0 +1,238 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_IC_STATE_H_
+#define V8_IC_STATE_H_
+
+#include "src/macro-assembler.h"
+
+namespace v8 {
+namespace internal {
+
+
+const int kMaxKeyedPolymorphism = 4;
+
+
+class ICUtility : public AllStatic {
+ public:
+  // Clear the inline cache to initial state.
+  static void Clear(Isolate* isolate, Address address,
+                    ConstantPoolArray* constant_pool);
+};
+
+
+class CallICState FINAL BASE_EMBEDDED {
+ public:
+  explicit CallICState(ExtraICState extra_ic_state);
+
+  enum CallType { METHOD, FUNCTION };
+
+  CallICState(int argc, CallType call_type)
+      : argc_(argc), call_type_(call_type) {}
+
+  ExtraICState GetExtraICState() const;
+
+  static void GenerateAheadOfTime(Isolate*,
+                                  void (*Generate)(Isolate*,
+                                                   const CallICState&));
+
+  int arg_count() const { return argc_; }
+  CallType call_type() const { return call_type_; }
+
+  bool CallAsMethod() const { return call_type_ == METHOD; }
+
+ private:
+  class ArgcBits : public BitField<int, 0, Code::kArgumentsBits> {};
+  class CallTypeBits : public BitField<CallType, Code::kArgumentsBits, 1> {};
+
+  const int argc_;
+  const CallType call_type_;
+};
+
+
+OStream& operator<<(OStream& os, const CallICState& s);
+
+
+// Mode to overwrite BinaryExpression values.
+enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
+
+class BinaryOpICState FINAL BASE_EMBEDDED {
+ public:
+  BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state);
+
+  BinaryOpICState(Isolate* isolate, Token::Value op, OverwriteMode mode)
+      : op_(op),
+        mode_(mode),
+        left_kind_(NONE),
+        right_kind_(NONE),
+        result_kind_(NONE),
+        isolate_(isolate) {
+    DCHECK_LE(FIRST_TOKEN, op);
+    DCHECK_LE(op, LAST_TOKEN);
+  }
+
+  InlineCacheState GetICState() const {
+    if (Max(left_kind_, right_kind_) == NONE) {
+      return ::v8::internal::UNINITIALIZED;
+    }
+    if (Max(left_kind_, right_kind_) == GENERIC) {
+      return ::v8::internal::MEGAMORPHIC;
+    }
+    if (Min(left_kind_, right_kind_) == GENERIC) {
+      return ::v8::internal::GENERIC;
+    }
+    return ::v8::internal::MONOMORPHIC;
+  }
+
+  ExtraICState GetExtraICState() const;
+
+  static void GenerateAheadOfTime(Isolate*,
+                                  void (*Generate)(Isolate*,
+                                                   const BinaryOpICState&));
+
+  bool CanReuseDoubleBox() const {
+    return (result_kind_ > SMI && result_kind_ <= NUMBER) &&
+           ((mode_ == OVERWRITE_LEFT && left_kind_ > SMI &&
+             left_kind_ <= NUMBER) ||
+            (mode_ == OVERWRITE_RIGHT && right_kind_ > SMI &&
+             right_kind_ <= NUMBER));
+  }
+
+  // Returns true if the IC _could_ create allocation mementos.
+  bool CouldCreateAllocationMementos() const {
+    if (left_kind_ == STRING || right_kind_ == STRING) {
+      DCHECK_EQ(Token::ADD, op_);
+      return true;
+    }
+    return false;
+  }
+
+  // Returns true if the IC _should_ create allocation mementos.
+  bool ShouldCreateAllocationMementos() const {
+    return FLAG_allocation_site_pretenuring && CouldCreateAllocationMementos();
+  }
+
+  bool HasSideEffects() const {
+    return Max(left_kind_, right_kind_) == GENERIC;
+  }
+
+  // Returns true if the IC should enable the inline smi code (i.e. if either
+  // parameter may be a smi).
+  bool UseInlinedSmiCode() const {
+    return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_);
+  }
+
+  static const int FIRST_TOKEN = Token::BIT_OR;
+  static const int LAST_TOKEN = Token::MOD;
+
+  Token::Value op() const { return op_; }
+  OverwriteMode mode() const { return mode_; }
+  Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
+
+  Type* GetLeftType(Zone* zone) const { return KindToType(left_kind_, zone); }
+  Type* GetRightType(Zone* zone) const { return KindToType(right_kind_, zone); }
+  Type* GetResultType(Zone* zone) const;
+
+  void Update(Handle<Object> left, Handle<Object> right, Handle<Object> result);
+
+  Isolate* isolate() const { return isolate_; }
+
+ private:
+  friend OStream& operator<<(OStream& os, const BinaryOpICState& s);
+
+  enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
+
+  Kind UpdateKind(Handle<Object> object, Kind kind) const;
+
+  static const char* KindToString(Kind kind);
+  static Type* KindToType(Kind kind, Zone* zone);
+  static bool KindMaybeSmi(Kind kind) {
+    return (kind >= SMI && kind <= NUMBER) || kind == GENERIC;
+  }
+
+  // We truncate the last bit of the token.
+  STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
+  class OpField : public BitField<int, 0, 4> {};
+  class OverwriteModeField : public BitField<OverwriteMode, 4, 2> {};
+  class ResultKindField : public BitField<Kind, 6, 3> {};
+  class LeftKindField : public BitField<Kind, 9, 3> {};
+  // When fixed right arg is set, we don't need to store the right kind.
+  // Thus the two fields can overlap.
+  class HasFixedRightArgField : public BitField<bool, 12, 1> {};
+  class FixedRightArgValueField : public BitField<int, 13, 4> {};
+  class RightKindField : public BitField<Kind, 13, 3> {};
+
+  Token::Value op_;
+  OverwriteMode mode_;
+  Kind left_kind_;
+  Kind right_kind_;
+  Kind result_kind_;
+  Maybe<int> fixed_right_arg_;
+  Isolate* isolate_;
+};
+
+
+OStream& operator<<(OStream& os, const BinaryOpICState& s);
+
+
+class CompareICState {
+ public:
+  // The type/state lattice is defined by the following inequations:
+  //   UNINITIALIZED < ...
+  //   ... < GENERIC
+  //   SMI < NUMBER
+  //   INTERNALIZED_STRING < STRING
+  //   KNOWN_OBJECT < OBJECT
+  enum State {
+    UNINITIALIZED,
+    SMI,
+    NUMBER,
+    STRING,
+    INTERNALIZED_STRING,
+    UNIQUE_NAME,   // Symbol or InternalizedString
+    OBJECT,        // JSObject
+    KNOWN_OBJECT,  // JSObject with specific map (faster check)
+    GENERIC
+  };
+
+  static Type* StateToType(Zone* zone, State state,
+                           Handle<Map> map = Handle<Map>());
+
+  static State NewInputState(State old_state, Handle<Object> value);
+
+  static const char* GetStateName(CompareICState::State state);
+
+  static State TargetState(State old_state, State old_left, State old_right,
+                           Token::Value op, bool has_inlined_smi_code,
+                           Handle<Object> x, Handle<Object> y);
+};
+
+
+class LoadICState FINAL BASE_EMBEDDED {
+ public:
+  explicit LoadICState(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
+
+  explicit LoadICState(ContextualMode mode)
+      : state_(ContextualModeBits::encode(mode)) {}
+
+  ExtraICState GetExtraICState() const { return state_; }
+
+  ContextualMode contextual_mode() const {
+    return ContextualModeBits::decode(state_);
+  }
+
+  static ContextualMode GetContextualMode(ExtraICState state) {
+    return LoadICState(state).contextual_mode();
+  }
+
+ private:
+  class ContextualModeBits : public BitField<ContextualMode, 0, 1> {};
+  STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
+
+  const ExtraICState state_;
+};
+}
+}
+
+#endif  // V8_IC_STATE_H_
index 374b5aa..17b7dca 100644 (file)
@@ -551,7 +551,7 @@ void CompareIC::Clear(Isolate* isolate, Address address, Code* target,
   DCHECK(CodeStub::GetMajorKey(target) == CodeStub::CompareIC);
   CompareICStub stub(target->stub_key(), isolate);
   // Only clear CompareICs that can retain objects.
-  if (stub.state() != KNOWN_OBJECT) return;
+  if (stub.state() != CompareICState::KNOWN_OBJECT) return;
   SetTargetAtAddress(address, GetRawUninitialized(isolate, stub.op()),
                      constant_pool);
   PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK);
@@ -814,7 +814,7 @@ Handle<Code> LoadIC::initialize_stub(Isolate* isolate,
 
 Handle<Code> LoadIC::megamorphic_stub() {
   if (kind() == Code::LOAD_IC) {
-    MegamorphicLoadStub stub(isolate(), State(extra_ic_state()));
+    MegamorphicLoadStub stub(isolate(), LoadICState(extra_ic_state()));
     return stub.GetCode();
   } else {
     DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
@@ -1336,16 +1336,9 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
 }
 
 
-OStream& operator<<(OStream& os, const CallIC::State& s) {
-  return os << "(args(" << s.arg_count() << "), "
-            << (s.call_type() == CallIC::METHOD ? "METHOD" : "FUNCTION")
-            << ", ";
-}
-
-
 Handle<Code> CallIC::initialize_stub(Isolate* isolate, int argc,
-                                     CallType call_type) {
-  CallICStub stub(isolate, State(argc, call_type));
+                                     CallICState::CallType call_type) {
+  CallICStub stub(isolate, CallICState(argc, call_type));
   Handle<Code> code = stub.GetCode();
   return code;
 }
@@ -1832,21 +1825,9 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
 }
 
 
-CallIC::State::State(ExtraICState extra_ic_state)
-    : argc_(ArgcBits::decode(extra_ic_state)),
-      call_type_(CallTypeBits::decode(extra_ic_state)) {}
-
-
-ExtraICState CallIC::State::GetExtraICState() const {
-  ExtraICState extra_ic_state =
-      ArgcBits::encode(argc_) | CallTypeBits::encode(call_type_);
-  return extra_ic_state;
-}
-
-
 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
                              Handle<FixedArray> vector, Handle<Smi> slot,
-                             const State& state) {
+                             const CallICState& state) {
   DCHECK(FLAG_use_ic && function->IsJSFunction());
 
   // Are we the array function?
@@ -1881,7 +1862,7 @@ bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
 
 void CallIC::PatchMegamorphic(Handle<Object> function,
                               Handle<FixedArray> vector, Handle<Smi> slot) {
-  State state(target()->extra_ic_state());
+  CallICState state(target()->extra_ic_state());
   IC::State old_state = FeedbackToState(vector, slot);
 
   // We are going generic.
@@ -1906,7 +1887,7 @@ void CallIC::PatchMegamorphic(Handle<Object> function,
 
 void CallIC::HandleMiss(Handle<Object> receiver, Handle<Object> function,
                         Handle<FixedArray> vector, Handle<Smi> slot) {
-  State state(target()->extra_ic_state());
+  CallICState state(target()->extra_ic_state());
   IC::State old_state = FeedbackToState(vector, slot);
   Handle<Object> name = isolate()->factory()->empty_string();
   Object* feedback = vector->get(slot->value());
@@ -2169,430 +2150,10 @@ RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss) {
 }
 
 
-BinaryOpIC::State::State(Isolate* isolate, ExtraICState extra_ic_state)
-    : isolate_(isolate) {
-  op_ =
-      static_cast<Token::Value>(FIRST_TOKEN + OpField::decode(extra_ic_state));
-  mode_ = OverwriteModeField::decode(extra_ic_state);
-  fixed_right_arg_ =
-      Maybe<int>(HasFixedRightArgField::decode(extra_ic_state),
-                 1 << FixedRightArgValueField::decode(extra_ic_state));
-  left_kind_ = LeftKindField::decode(extra_ic_state);
-  if (fixed_right_arg_.has_value) {
-    right_kind_ = Smi::IsValid(fixed_right_arg_.value) ? SMI : INT32;
-  } else {
-    right_kind_ = RightKindField::decode(extra_ic_state);
-  }
-  result_kind_ = ResultKindField::decode(extra_ic_state);
-  DCHECK_LE(FIRST_TOKEN, op_);
-  DCHECK_LE(op_, LAST_TOKEN);
-}
-
-
-ExtraICState BinaryOpIC::State::GetExtraICState() const {
-  ExtraICState extra_ic_state =
-      OpField::encode(op_ - FIRST_TOKEN) | OverwriteModeField::encode(mode_) |
-      LeftKindField::encode(left_kind_) |
-      ResultKindField::encode(result_kind_) |
-      HasFixedRightArgField::encode(fixed_right_arg_.has_value);
-  if (fixed_right_arg_.has_value) {
-    extra_ic_state = FixedRightArgValueField::update(
-        extra_ic_state, WhichPowerOf2(fixed_right_arg_.value));
-  } else {
-    extra_ic_state = RightKindField::update(extra_ic_state, right_kind_);
-  }
-  return extra_ic_state;
-}
-
-
-// static
-void BinaryOpIC::State::GenerateAheadOfTime(Isolate* isolate,
-                                            void (*Generate)(Isolate*,
-                                                             const State&)) {
-// TODO(olivf) We should investigate why adding stubs to the snapshot is so
-// expensive at runtime. When solved we should be able to add most binops to
-// the snapshot instead of hand-picking them.
-// Generated list of commonly used stubs
-#define GENERATE(op, left_kind, right_kind, result_kind, mode) \
-  do {                                                         \
-    State state(isolate, op, mode);                            \
-    state.left_kind_ = left_kind;                              \
-    state.fixed_right_arg_.has_value = false;                  \
-    state.right_kind_ = right_kind;                            \
-    state.result_kind_ = result_kind;                          \
-    Generate(isolate, state);                                  \
-  } while (false)
-  GENERATE(Token::ADD, INT32, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::ADD, INT32, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, INT32, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, INT32, INT32, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, INT32, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::ADD, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::ADD, NUMBER, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::ADD, NUMBER, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::ADD, SMI, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::ADD, SMI, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, SMI, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, SMI, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, INT32, INT32, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, INT32, INT32, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, INT32, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, NUMBER, INT32, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, SMI, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, SMI, INT32, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, SMI, NUMBER, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, INT32, INT32, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, INT32, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_OR, INT32, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, SMI, INT32, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_XOR, INT32, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_XOR, INT32, INT32, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, INT32, INT32, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_XOR, INT32, NUMBER, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_XOR, NUMBER, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, NUMBER, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, NUMBER, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, SMI, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, SMI, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_XOR, SMI, INT32, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_XOR, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::DIV, INT32, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::DIV, INT32, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, INT32, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::DIV, INT32, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, NUMBER, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::DIV, NUMBER, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, SMI, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::DIV, SMI, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, SMI, INT32, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, SMI, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::DIV, SMI, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::DIV, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::MOD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MOD, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::MOD, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, INT32, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::MUL, INT32, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, INT32, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::MUL, INT32, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, INT32, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, NUMBER, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, NUMBER, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::MUL, SMI, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::MUL, SMI, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, SMI, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, SMI, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::MUL, SMI, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::MUL, SMI, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, SMI, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SAR, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::SAR, INT32, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SAR, INT32, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SAR, NUMBER, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SAR, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SHL, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::SHL, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::SHL, INT32, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SHL, INT32, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SHL, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SHL, SMI, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::SHL, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SHR, INT32, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SHR, NUMBER, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SHR, NUMBER, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::SHR, NUMBER, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::SHR, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SUB, INT32, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::SUB, INT32, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, INT32, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::SUB, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::SUB, NUMBER, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::SUB, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::SUB, NUMBER, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::SUB, SMI, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::SUB, SMI, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::SUB, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_RIGHT);
-#undef GENERATE
-#define GENERATE(op, left_kind, fixed_right_arg_value, result_kind, mode) \
-  do {                                                                    \
-    State state(isolate, op, mode);                                       \
-    state.left_kind_ = left_kind;                                         \
-    state.fixed_right_arg_.has_value = true;                              \
-    state.fixed_right_arg_.value = fixed_right_arg_value;                 \
-    state.right_kind_ = SMI;                                              \
-    state.result_kind_ = result_kind;                                     \
-    Generate(isolate, state);                                             \
-  } while (false)
-  GENERATE(Token::MOD, SMI, 2, SMI, NO_OVERWRITE);
-  GENERATE(Token::MOD, SMI, 4, SMI, NO_OVERWRITE);
-  GENERATE(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::MOD, SMI, 8, SMI, NO_OVERWRITE);
-  GENERATE(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::MOD, SMI, 32, SMI, NO_OVERWRITE);
-  GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE);
-#undef GENERATE
-}
-
-
-Type* BinaryOpIC::State::GetResultType(Zone* zone) const {
-  Kind result_kind = result_kind_;
-  if (HasSideEffects()) {
-    result_kind = NONE;
-  } else if (result_kind == GENERIC && op_ == Token::ADD) {
-    return Type::Union(Type::Number(zone), Type::String(zone), zone);
-  } else if (result_kind == NUMBER && op_ == Token::SHR) {
-    return Type::Unsigned32(zone);
-  }
-  DCHECK_NE(GENERIC, result_kind);
-  return KindToType(result_kind, zone);
-}
-
-
-OStream& operator<<(OStream& os, const BinaryOpIC::State& s) {
-  os << "(" << Token::Name(s.op_);
-  if (s.mode_ == OVERWRITE_LEFT)
-    os << "_ReuseLeft";
-  else if (s.mode_ == OVERWRITE_RIGHT)
-    os << "_ReuseRight";
-  if (s.CouldCreateAllocationMementos()) os << "_CreateAllocationMementos";
-  os << ":" << BinaryOpIC::State::KindToString(s.left_kind_) << "*";
-  if (s.fixed_right_arg_.has_value) {
-    os << s.fixed_right_arg_.value;
-  } else {
-    os << BinaryOpIC::State::KindToString(s.right_kind_);
-  }
-  return os << "->" << BinaryOpIC::State::KindToString(s.result_kind_) << ")";
-}
-
-
-void BinaryOpIC::State::Update(Handle<Object> left, Handle<Object> right,
-                               Handle<Object> result) {
-  ExtraICState old_extra_ic_state = GetExtraICState();
-
-  left_kind_ = UpdateKind(left, left_kind_);
-  right_kind_ = UpdateKind(right, right_kind_);
-
-  int32_t fixed_right_arg_value = 0;
-  bool has_fixed_right_arg =
-      op_ == Token::MOD && right->ToInt32(&fixed_right_arg_value) &&
-      fixed_right_arg_value > 0 &&
-      base::bits::IsPowerOfTwo32(fixed_right_arg_value) &&
-      FixedRightArgValueField::is_valid(WhichPowerOf2(fixed_right_arg_value)) &&
-      (left_kind_ == SMI || left_kind_ == INT32) &&
-      (result_kind_ == NONE || !fixed_right_arg_.has_value);
-  fixed_right_arg_ = Maybe<int32_t>(has_fixed_right_arg, fixed_right_arg_value);
-
-  result_kind_ = UpdateKind(result, result_kind_);
-
-  if (!Token::IsTruncatingBinaryOp(op_)) {
-    Kind input_kind = Max(left_kind_, right_kind_);
-    if (result_kind_ < input_kind && input_kind <= NUMBER) {
-      result_kind_ = input_kind;
-    }
-  }
-
-  // We don't want to distinguish INT32 and NUMBER for string add (because
-  // NumberToString can't make use of this anyway).
-  if (left_kind_ == STRING && right_kind_ == INT32) {
-    DCHECK_EQ(STRING, result_kind_);
-    DCHECK_EQ(Token::ADD, op_);
-    right_kind_ = NUMBER;
-  } else if (right_kind_ == STRING && left_kind_ == INT32) {
-    DCHECK_EQ(STRING, result_kind_);
-    DCHECK_EQ(Token::ADD, op_);
-    left_kind_ = NUMBER;
-  }
-
-  // Reset overwrite mode unless we can actually make use of it, or may be able
-  // to make use of it at some point in the future.
-  if ((mode_ == OVERWRITE_LEFT && left_kind_ > NUMBER) ||
-      (mode_ == OVERWRITE_RIGHT && right_kind_ > NUMBER) ||
-      result_kind_ > NUMBER) {
-    mode_ = NO_OVERWRITE;
-  }
-
-  if (old_extra_ic_state == GetExtraICState()) {
-    // Tagged operations can lead to non-truncating HChanges
-    if (left->IsUndefined() || left->IsBoolean()) {
-      left_kind_ = GENERIC;
-    } else {
-      DCHECK(right->IsUndefined() || right->IsBoolean());
-      right_kind_ = GENERIC;
-    }
-  }
-}
-
-
-BinaryOpIC::State::Kind BinaryOpIC::State::UpdateKind(Handle<Object> object,
-                                                      Kind kind) const {
-  Kind new_kind = GENERIC;
-  bool is_truncating = Token::IsTruncatingBinaryOp(op());
-  if (object->IsBoolean() && is_truncating) {
-    // Booleans will be automatically truncated by HChange.
-    new_kind = INT32;
-  } else if (object->IsUndefined()) {
-    // Undefined will be automatically truncated by HChange.
-    new_kind = is_truncating ? INT32 : NUMBER;
-  } else if (object->IsSmi()) {
-    new_kind = SMI;
-  } else if (object->IsHeapNumber()) {
-    double value = Handle<HeapNumber>::cast(object)->value();
-    new_kind = IsInt32Double(value) ? INT32 : NUMBER;
-  } else if (object->IsString() && op() == Token::ADD) {
-    new_kind = STRING;
-  }
-  if (new_kind == INT32 && SmiValuesAre32Bits()) {
-    new_kind = NUMBER;
-  }
-  if (kind != NONE && ((new_kind <= NUMBER && kind > NUMBER) ||
-                       (new_kind > NUMBER && kind <= NUMBER))) {
-    new_kind = GENERIC;
-  }
-  return Max(kind, new_kind);
-}
-
-
-// static
-const char* BinaryOpIC::State::KindToString(Kind kind) {
-  switch (kind) {
-    case NONE:
-      return "None";
-    case SMI:
-      return "Smi";
-    case INT32:
-      return "Int32";
-    case NUMBER:
-      return "Number";
-    case STRING:
-      return "String";
-    case GENERIC:
-      return "Generic";
-  }
-  UNREACHABLE();
-  return NULL;
-}
-
-
-// static
-Type* BinaryOpIC::State::KindToType(Kind kind, Zone* zone) {
-  switch (kind) {
-    case NONE:
-      return Type::None(zone);
-    case SMI:
-      return Type::SignedSmall(zone);
-    case INT32:
-      return Type::Signed32(zone);
-    case NUMBER:
-      return Type::Number(zone);
-    case STRING:
-      return Type::String(zone);
-    case GENERIC:
-      return Type::Any(zone);
-  }
-  UNREACHABLE();
-  return NULL;
-}
-
-
 MaybeHandle<Object> BinaryOpIC::Transition(
     Handle<AllocationSite> allocation_site, Handle<Object> left,
     Handle<Object> right) {
-  State state(isolate(), target()->extra_ic_state());
+  BinaryOpICState state(isolate(), target()->extra_ic_state());
 
   // Compute the actual result using the builtin for the binary operation.
   Object* builtin = isolate()->js_builtins_object()->javascript_builtin(
@@ -2607,7 +2168,7 @@ MaybeHandle<Object> BinaryOpIC::Transition(
   // update the state of this very IC, so we must update the stored state.
   UpdateTarget();
   // Compute the new state.
-  State old_state(isolate(), target()->extra_ic_state());
+  BinaryOpICState old_state(isolate(), target()->extra_ic_state());
   state.Update(left, right, result);
 
   // Check if we have a string operation here.
@@ -2689,7 +2250,9 @@ RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite) {
 
 
 Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) {
-  CompareICStub stub(isolate, op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED);
+  CompareICStub stub(isolate, op, CompareICState::UNINITIALIZED,
+                     CompareICState::UNINITIALIZED,
+                     CompareICState::UNINITIALIZED);
   Code* code = NULL;
   CHECK(stub.FindCodeInCache(&code));
   return code;
@@ -2697,177 +2260,25 @@ Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) {
 
 
 Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) {
-  CompareICStub stub(isolate, op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED);
+  CompareICStub stub(isolate, op, CompareICState::UNINITIALIZED,
+                     CompareICState::UNINITIALIZED,
+                     CompareICState::UNINITIALIZED);
   return stub.GetCode();
 }
 
 
-const char* CompareIC::GetStateName(State state) {
-  switch (state) {
-    case UNINITIALIZED:
-      return "UNINITIALIZED";
-    case SMI:
-      return "SMI";
-    case NUMBER:
-      return "NUMBER";
-    case INTERNALIZED_STRING:
-      return "INTERNALIZED_STRING";
-    case STRING:
-      return "STRING";
-    case UNIQUE_NAME:
-      return "UNIQUE_NAME";
-    case OBJECT:
-      return "OBJECT";
-    case KNOWN_OBJECT:
-      return "KNOWN_OBJECT";
-    case GENERIC:
-      return "GENERIC";
-  }
-  UNREACHABLE();
-  return NULL;
-}
-
-
-Type* CompareIC::StateToType(Zone* zone, CompareIC::State state,
-                             Handle<Map> map) {
-  switch (state) {
-    case CompareIC::UNINITIALIZED:
-      return Type::None(zone);
-    case CompareIC::SMI:
-      return Type::SignedSmall(zone);
-    case CompareIC::NUMBER:
-      return Type::Number(zone);
-    case CompareIC::STRING:
-      return Type::String(zone);
-    case CompareIC::INTERNALIZED_STRING:
-      return Type::InternalizedString(zone);
-    case CompareIC::UNIQUE_NAME:
-      return Type::UniqueName(zone);
-    case CompareIC::OBJECT:
-      return Type::Receiver(zone);
-    case CompareIC::KNOWN_OBJECT:
-      return map.is_null() ? Type::Receiver(zone) : Type::Class(map, zone);
-    case CompareIC::GENERIC:
-      return Type::Any(zone);
-  }
-  UNREACHABLE();
-  return NULL;
-}
-
-
-CompareIC::State CompareIC::NewInputState(State old_state,
-                                          Handle<Object> value) {
-  switch (old_state) {
-    case UNINITIALIZED:
-      if (value->IsSmi()) return SMI;
-      if (value->IsHeapNumber()) return NUMBER;
-      if (value->IsInternalizedString()) return INTERNALIZED_STRING;
-      if (value->IsString()) return STRING;
-      if (value->IsSymbol()) return UNIQUE_NAME;
-      if (value->IsJSObject()) return OBJECT;
-      break;
-    case SMI:
-      if (value->IsSmi()) return SMI;
-      if (value->IsHeapNumber()) return NUMBER;
-      break;
-    case NUMBER:
-      if (value->IsNumber()) return NUMBER;
-      break;
-    case INTERNALIZED_STRING:
-      if (value->IsInternalizedString()) return INTERNALIZED_STRING;
-      if (value->IsString()) return STRING;
-      if (value->IsSymbol()) return UNIQUE_NAME;
-      break;
-    case STRING:
-      if (value->IsString()) return STRING;
-      break;
-    case UNIQUE_NAME:
-      if (value->IsUniqueName()) return UNIQUE_NAME;
-      break;
-    case OBJECT:
-      if (value->IsJSObject()) return OBJECT;
-      break;
-    case GENERIC:
-      break;
-    case KNOWN_OBJECT:
-      UNREACHABLE();
-      break;
-  }
-  return GENERIC;
-}
-
-
-CompareIC::State CompareIC::TargetState(State old_state, State old_left,
-                                        State old_right,
-                                        bool has_inlined_smi_code,
-                                        Handle<Object> x, Handle<Object> y) {
-  switch (old_state) {
-    case UNINITIALIZED:
-      if (x->IsSmi() && y->IsSmi()) return SMI;
-      if (x->IsNumber() && y->IsNumber()) return NUMBER;
-      if (Token::IsOrderedRelationalCompareOp(op_)) {
-        // Ordered comparisons treat undefined as NaN, so the
-        // NUMBER stub will do the right thing.
-        if ((x->IsNumber() && y->IsUndefined()) ||
-            (y->IsNumber() && x->IsUndefined())) {
-          return NUMBER;
-        }
-      }
-      if (x->IsInternalizedString() && y->IsInternalizedString()) {
-        // We compare internalized strings as plain ones if we need to determine
-        // the order in a non-equality compare.
-        return Token::IsEqualityOp(op_) ? INTERNALIZED_STRING : STRING;
-      }
-      if (x->IsString() && y->IsString()) return STRING;
-      if (!Token::IsEqualityOp(op_)) return GENERIC;
-      if (x->IsUniqueName() && y->IsUniqueName()) return UNIQUE_NAME;
-      if (x->IsJSObject() && y->IsJSObject()) {
-        if (Handle<JSObject>::cast(x)->map() ==
-            Handle<JSObject>::cast(y)->map()) {
-          return KNOWN_OBJECT;
-        } else {
-          return OBJECT;
-        }
-      }
-      return GENERIC;
-    case SMI:
-      return x->IsNumber() && y->IsNumber() ? NUMBER : GENERIC;
-    case INTERNALIZED_STRING:
-      DCHECK(Token::IsEqualityOp(op_));
-      if (x->IsString() && y->IsString()) return STRING;
-      if (x->IsUniqueName() && y->IsUniqueName()) return UNIQUE_NAME;
-      return GENERIC;
-    case NUMBER:
-      // If the failure was due to one side changing from smi to heap number,
-      // then keep the state (if other changed at the same time, we will get
-      // a second miss and then go to generic).
-      if (old_left == SMI && x->IsHeapNumber()) return NUMBER;
-      if (old_right == SMI && y->IsHeapNumber()) return NUMBER;
-      return GENERIC;
-    case KNOWN_OBJECT:
-      DCHECK(Token::IsEqualityOp(op_));
-      if (x->IsJSObject() && y->IsJSObject()) return OBJECT;
-      return GENERIC;
-    case STRING:
-    case UNIQUE_NAME:
-    case OBJECT:
-    case GENERIC:
-      return GENERIC;
-  }
-  UNREACHABLE();
-  return GENERIC;  // Make the compiler happy.
-}
-
-
 Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
   HandleScope scope(isolate());
   CompareICStub old_stub(target()->stub_key(), isolate());
-  State new_left = NewInputState(old_stub.left(), x);
-  State new_right = NewInputState(old_stub.right(), y);
-  State state = TargetState(old_stub.state(), old_stub.left(), old_stub.right(),
-                            HasInlinedSmiCode(address()), x, y);
+  CompareICState::State new_left =
+      CompareICState::NewInputState(old_stub.left(), x);
+  CompareICState::State new_right =
+      CompareICState::NewInputState(old_stub.right(), y);
+  CompareICState::State state = CompareICState::TargetState(
+      old_stub.state(), old_stub.left(), old_stub.right(), op_,
+      HasInlinedSmiCode(address()), x, y);
   CompareICStub stub(isolate(), op_, new_left, new_right, state);
-  if (state == KNOWN_OBJECT) {
+  if (state == CompareICState::KNOWN_OBJECT) {
     stub.set_known_map(
         Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate()));
   }
@@ -2878,14 +2289,17 @@ Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
     PrintF("[CompareIC in ");
     JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
     PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n",
-           GetStateName(old_stub.left()), GetStateName(old_stub.right()),
-           GetStateName(old_stub.state()), GetStateName(new_left),
-           GetStateName(new_right), GetStateName(state), Token::Name(op_),
+           CompareICState::GetStateName(old_stub.left()),
+           CompareICState::GetStateName(old_stub.right()),
+           CompareICState::GetStateName(old_stub.state()),
+           CompareICState::GetStateName(new_left),
+           CompareICState::GetStateName(new_right),
+           CompareICState::GetStateName(state), Token::Name(op_),
            static_cast<void*>(*stub.GetCode()));
   }
 
   // Activate inlined smi code.
-  if (old_stub.state() == UNINITIALIZED) {
+  if (old_stub.state() == CompareICState::UNINITIALIZED) {
     PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK);
   }
 
index 41d5494..549cc20 100644 (file)
@@ -5,15 +5,13 @@
 #ifndef V8_IC_H_
 #define V8_IC_H_
 
+#include "src/ic/ic-state.h"
 #include "src/macro-assembler.h"
 
 namespace v8 {
 namespace internal {
 
 
-const int kMaxKeyedPolymorphism = 4;
-
-
 // IC_UTIL_LIST defines all utility functions called from generated
 // inline caching code. The argument for the macro, ICU, is the function name.
 #define IC_UTIL_LIST(ICU)              \
@@ -217,7 +215,7 @@ class IC {
   void TargetTypes(TypeHandleList* list) {
     FindTargetMaps();
     for (int i = 0; i < target_maps_.length(); i++) {
-      list->Add(IC::MapToType<HeapType>(target_maps_.at(i), isolate_));
+      list->Add(MapToType<HeapType>(target_maps_.at(i), isolate_));
     }
   }
 
@@ -295,32 +293,6 @@ class IC_Utility {
 
 class CallIC : public IC {
  public:
-  enum CallType { METHOD, FUNCTION };
-
-  class State FINAL BASE_EMBEDDED {
-   public:
-    explicit State(ExtraICState extra_ic_state);
-
-    State(int argc, CallType call_type) : argc_(argc), call_type_(call_type) {}
-
-    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_; }
-
-    bool CallAsMethod() const { return call_type_ == METHOD; }
-
-   private:
-    class ArgcBits : public BitField<int, 0, Code::kArgumentsBits> {};
-    class CallTypeBits : public BitField<CallType, Code::kArgumentsBits, 1> {};
-
-    const int argc_;
-    const CallType call_type_;
-  };
-
   explicit CallIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
 
   void PatchMegamorphic(Handle<Object> function, Handle<FixedArray> vector,
@@ -332,11 +304,11 @@ class CallIC : public IC {
   // Returns true if a custom handler was installed.
   bool DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
                        Handle<FixedArray> vector, Handle<Smi> slot,
-                       const State& state);
+                       const CallICState& state);
 
   // Code generator routines.
   static Handle<Code> initialize_stub(Isolate* isolate, int argc,
-                                      CallType call_type);
+                                      CallICState::CallType call_type);
 
   static void Clear(Isolate* isolate, Address address, Code* target,
                     ConstantPoolArray* constant_pool);
@@ -347,41 +319,14 @@ class CallIC : public IC {
 };
 
 
-OStream& operator<<(OStream& os, const CallIC::State& s);
-
-
 class LoadIC : public IC {
  public:
-  class State FINAL BASE_EMBEDDED {
-   public:
-    explicit State(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
-
-    explicit State(ContextualMode mode)
-        : state_(ContextualModeBits::encode(mode)) {}
-
-    ExtraICState GetExtraICState() const { return state_; }
-
-    ContextualMode contextual_mode() const {
-      return ContextualModeBits::decode(state_);
-    }
-
-   private:
-    class ContextualModeBits : public BitField<ContextualMode, 0, 1> {};
-    STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
-
-    const ExtraICState state_;
-  };
-
   static ExtraICState ComputeExtraICState(ContextualMode contextual_mode) {
-    return State(contextual_mode).GetExtraICState();
-  }
-
-  static ContextualMode GetContextualMode(ExtraICState state) {
-    return State(state).contextual_mode();
+    return LoadICState(contextual_mode).GetExtraICState();
   }
 
   ContextualMode contextual_mode() const {
-    return GetContextualMode(extra_ic_state());
+    return LoadICState::GetContextualMode(extra_ic_state());
   }
 
   explicit LoadIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) {
@@ -683,130 +628,9 @@ class KeyedStoreIC : public StoreIC {
 };
 
 
-// Mode to overwrite BinaryExpression values.
-enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
-
 // Type Recording BinaryOpIC, that records the types of the inputs and outputs.
 class BinaryOpIC : public IC {
  public:
-  class State FINAL BASE_EMBEDDED {
-   public:
-    State(Isolate* isolate, ExtraICState extra_ic_state);
-
-    State(Isolate* isolate, Token::Value op, OverwriteMode mode)
-        : op_(op),
-          mode_(mode),
-          left_kind_(NONE),
-          right_kind_(NONE),
-          result_kind_(NONE),
-          isolate_(isolate) {
-      DCHECK_LE(FIRST_TOKEN, op);
-      DCHECK_LE(op, LAST_TOKEN);
-    }
-
-    InlineCacheState GetICState() const {
-      if (Max(left_kind_, right_kind_) == NONE) {
-        return ::v8::internal::UNINITIALIZED;
-      }
-      if (Max(left_kind_, right_kind_) == GENERIC) {
-        return ::v8::internal::MEGAMORPHIC;
-      }
-      if (Min(left_kind_, right_kind_) == GENERIC) {
-        return ::v8::internal::GENERIC;
-      }
-      return ::v8::internal::MONOMORPHIC;
-    }
-
-    ExtraICState GetExtraICState() const;
-
-    static void GenerateAheadOfTime(Isolate*,
-                                    void (*Generate)(Isolate*, const State&));
-
-    bool CanReuseDoubleBox() const {
-      return (result_kind_ > SMI && result_kind_ <= NUMBER) &&
-             ((mode_ == OVERWRITE_LEFT && left_kind_ > SMI &&
-               left_kind_ <= NUMBER) ||
-              (mode_ == OVERWRITE_RIGHT && right_kind_ > SMI &&
-               right_kind_ <= NUMBER));
-    }
-
-    // Returns true if the IC _could_ create allocation mementos.
-    bool CouldCreateAllocationMementos() const {
-      if (left_kind_ == STRING || right_kind_ == STRING) {
-        DCHECK_EQ(Token::ADD, op_);
-        return true;
-      }
-      return false;
-    }
-
-    // Returns true if the IC _should_ create allocation mementos.
-    bool ShouldCreateAllocationMementos() const {
-      return FLAG_allocation_site_pretenuring &&
-             CouldCreateAllocationMementos();
-    }
-
-    bool HasSideEffects() const {
-      return Max(left_kind_, right_kind_) == GENERIC;
-    }
-
-    // Returns true if the IC should enable the inline smi code (i.e. if either
-    // parameter may be a smi).
-    bool UseInlinedSmiCode() const {
-      return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_);
-    }
-
-    static const int FIRST_TOKEN = Token::BIT_OR;
-    static const int LAST_TOKEN = Token::MOD;
-
-    Token::Value op() const { return op_; }
-    OverwriteMode mode() const { return mode_; }
-    Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
-
-    Type* GetLeftType(Zone* zone) const { return KindToType(left_kind_, zone); }
-    Type* GetRightType(Zone* zone) const {
-      return KindToType(right_kind_, zone);
-    }
-    Type* GetResultType(Zone* zone) const;
-
-    void Update(Handle<Object> left, Handle<Object> right,
-                Handle<Object> result);
-
-    Isolate* isolate() const { return isolate_; }
-
-   private:
-    friend OStream& operator<<(OStream& os, const BinaryOpIC::State& s);
-
-    enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
-
-    Kind UpdateKind(Handle<Object> object, Kind kind) const;
-
-    static const char* KindToString(Kind kind);
-    static Type* KindToType(Kind kind, Zone* zone);
-    static bool KindMaybeSmi(Kind kind) {
-      return (kind >= SMI && kind <= NUMBER) || kind == GENERIC;
-    }
-
-    // We truncate the last bit of the token.
-    STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
-    class OpField : public BitField<int, 0, 4> {};
-    class OverwriteModeField : public BitField<OverwriteMode, 4, 2> {};
-    class ResultKindField : public BitField<Kind, 6, 3> {};
-    class LeftKindField : public BitField<Kind, 9, 3> {};
-    // When fixed right arg is set, we don't need to store the right kind.
-    // Thus the two fields can overlap.
-    class HasFixedRightArgField : public BitField<bool, 12, 1> {};
-    class FixedRightArgValueField : public BitField<int, 13, 4> {};
-    class RightKindField : public BitField<Kind, 13, 3> {};
-
-    Token::Value op_;
-    OverwriteMode mode_;
-    Kind left_kind_;
-    Kind right_kind_;
-    Kind result_kind_;
-    Maybe<int> fixed_right_arg_;
-    Isolate* isolate_;
-  };
-
   explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
 
   static Builtins::JavaScript TokenToJSBuiltin(Token::Value op);
@@ -817,56 +641,23 @@ class BinaryOpIC : public IC {
 };
 
 
-OStream& operator<<(OStream& os, const BinaryOpIC::State& s);
-
-
 class CompareIC : public IC {
  public:
-  // The type/state lattice is defined by the following inequations:
-  //   UNINITIALIZED < ...
-  //   ... < GENERIC
-  //   SMI < NUMBER
-  //   INTERNALIZED_STRING < STRING
-  //   KNOWN_OBJECT < OBJECT
-  enum State {
-    UNINITIALIZED,
-    SMI,
-    NUMBER,
-    STRING,
-    INTERNALIZED_STRING,
-    UNIQUE_NAME,   // Symbol or InternalizedString
-    OBJECT,        // JSObject
-    KNOWN_OBJECT,  // JSObject with specific map (faster check)
-    GENERIC
-  };
-
-  static State NewInputState(State old_state, Handle<Object> value);
-
-  static Type* StateToType(Zone* zone, State state,
-                           Handle<Map> map = Handle<Map>());
-
   CompareIC(Isolate* isolate, Token::Value op)
       : IC(EXTRA_CALL_FRAME, isolate), op_(op) {}
 
   // Update the inline cache for the given operands.
   Code* UpdateCaches(Handle<Object> x, Handle<Object> y);
 
-
-  // Factory method for getting an uninitialized compare stub.
-  static Handle<Code> GetUninitialized(Isolate* isolate, Token::Value op);
-
   // Helper function for computing the condition for a compare operation.
   static Condition ComputeCondition(Token::Value op);
 
-  static const char* GetStateName(State state);
+  // Factory method for getting an uninitialized compare stub.
+  static Handle<Code> GetUninitialized(Isolate* isolate, Token::Value op);
 
  private:
   static bool HasInlinedSmiCode(Address address);
 
-  State TargetState(State old_state, State old_left, State old_right,
-                    bool has_inlined_smi_code, Handle<Object> x,
-                    Handle<Object> y);
-
   bool strict() const { return op_ == Token::EQ_STRICT; }
   Condition GetCondition() const { return ComputeCondition(op_); }
 
index 0cbaf13..5b4555f 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "src/ic/call-optimization.h"
 #include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
 
 namespace v8 {
 namespace internal {
index 8df6185..920b52a 100644 (file)
@@ -6,6 +6,7 @@
 
 #if V8_TARGET_ARCH_MIPS
 
+#include "src/ic/ic.h"
 #include "src/ic/ic-compiler.h"
 
 namespace v8 {
index 4422f50..3d7cc68 100644 (file)
@@ -6,6 +6,7 @@
 
 #if V8_TARGET_ARCH_X64
 
+#include "src/ic/ic.h"
 #include "src/ic/ic-compiler.h"
 
 namespace v8 {
index 963a83e..8523460 100644 (file)
@@ -11,6 +11,7 @@
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
@@ -597,12 +598,12 @@ static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm,
 
 static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input,
                                          Register scratch,
-                                         CompareIC::State expected,
+                                         CompareICState::State expected,
                                          Label* fail) {
   Label ok;
-  if (expected == CompareIC::SMI) {
+  if (expected == CompareICState::SMI) {
     __ JumpIfNotSmi(input, fail);
-  } else if (expected == CompareIC::NUMBER) {
+  } else if (expected == CompareICState::NUMBER) {
     __ JumpIfSmi(input, &ok);
     __ CheckMap(input, scratch, Heap::kHeapNumberMapRootIndex, fail,
                 DONT_DO_SMI_CHECK);
@@ -2749,7 +2750,7 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
   __ TailCallStub(&stub);
 
   __ bind(&miss);
-  GenerateMiss(masm, IC::kCallIC_Customization_Miss);
+  GenerateMiss(masm);
 
   // The slow case, we need this no matter what to complete a call after a miss.
   CallFunctionNoFeedback(masm,
@@ -2825,7 +2826,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
 
   // We are here because tracing is on or we are going monomorphic.
   __ bind(&miss);
-  GenerateMiss(masm, IC::kCallIC_Miss);
+  GenerateMiss(masm);
 
   // the slow case
   __ bind(&slow_start);
@@ -2840,7 +2841,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
 }
 
 
-void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
+void CallICStub::GenerateMiss(MacroAssembler* masm) {
   // Get the receiver of the function from the stack; 1 ~ return address.
   __ lw(t0, MemOperand(sp, (arg_count() + 1) * kPointerSize));
 
@@ -2851,6 +2852,9 @@ void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
     __ Push(t0, a1, a2, a3);
 
     // Call the entry.
+    IC::UtilityId id = GetICState() == DEFAULT ? IC::kCallIC_Miss
+                                               : IC::kCallIC_Customization_Miss;
+
     ExternalReference miss = ExternalReference(IC_Utility(id),
                                                masm->isolate());
     __ CallExternalReference(miss, 4);
@@ -3438,7 +3442,7 @@ void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateSmis(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::SMI);
+  DCHECK(state() == CompareICState::SMI);
   Label miss;
   __ Or(a2, a1, a0);
   __ JumpIfNotSmi(a2, &miss);
@@ -3461,16 +3465,16 @@ void CompareICStub::GenerateSmis(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::NUMBER);
+  DCHECK(state() == CompareICState::NUMBER);
 
   Label generic_stub;
   Label unordered, maybe_undefined1, maybe_undefined2;
   Label miss;
 
-  if (left() == CompareIC::SMI) {
+  if (left() == CompareICState::SMI) {
     __ JumpIfNotSmi(a1, &miss);
   }
-  if (right() == CompareIC::SMI) {
+  if (right() == CompareICState::SMI) {
     __ JumpIfNotSmi(a0, &miss);
   }
 
@@ -3528,8 +3532,8 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
 
   __ bind(&unordered);
   __ bind(&generic_stub);
-  CompareICStub stub(isolate(), op(), CompareIC::GENERIC, CompareIC::GENERIC,
-                     CompareIC::GENERIC);
+  CompareICStub stub(isolate(), op(), CompareICState::GENERIC,
+                     CompareICState::GENERIC, CompareICState::GENERIC);
   __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
 
   __ bind(&maybe_undefined1);
@@ -3554,7 +3558,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::INTERNALIZED_STRING);
+  DCHECK(state() == CompareICState::INTERNALIZED_STRING);
   Label miss;
 
   // Registers containing left and right operands respectively.
@@ -3594,7 +3598,7 @@ void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::UNIQUE_NAME);
+  DCHECK(state() == CompareICState::UNIQUE_NAME);
   DCHECK(GetCondition() == eq);
   Label miss;
 
@@ -3638,7 +3642,7 @@ void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateStrings(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::STRING);
+  DCHECK(state() == CompareICState::STRING);
   Label miss;
 
   bool equality = Token::IsEqualityOp(op());
@@ -3724,7 +3728,7 @@ void CompareICStub::GenerateStrings(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateObjects(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::OBJECT);
+  DCHECK(state() == CompareICState::OBJECT);
   Label miss;
   __ And(a2, a1, Operand(a0));
   __ JumpIfSmi(a2, &miss);
index e679a29..d524d2f 100644 (file)
@@ -20,6 +20,7 @@
 #include "src/compiler.h"
 #include "src/debug.h"
 #include "src/full-codegen.h"
+#include "src/ic/ic.h"
 #include "src/isolate-inl.h"
 #include "src/parser.h"
 #include "src/scopes.h"
@@ -2611,12 +2612,11 @@ void FullCodeGenerator::CallIC(Handle<Code> code,
 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
   Expression* callee = expr->expression();
 
-  CallIC::CallType call_type = callee->IsVariableProxy()
-      ? CallIC::FUNCTION
-      : CallIC::METHOD;
+  CallICState::CallType call_type =
+      callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD;
 
   // Get the target function.
-  if (call_type == CallIC::FUNCTION) {
+  if (call_type == CallICState::FUNCTION) {
     { StackValueContext context(this);
       EmitVariableLoad(callee->AsVariableProxy());
       PrepareForBailout(callee, NO_REGISTERS);
@@ -2660,11 +2660,11 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
   __ push(at);
   __ sw(v0, MemOperand(sp, kPointerSize));
 
-  EmitCall(expr, CallIC::METHOD);
+  EmitCall(expr, CallICState::METHOD);
 }
 
 
-void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
+void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Load the arguments.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
index e441472..001b1f8 100644 (file)
@@ -31,6 +31,7 @@
 #include "src/code-factory.h"
 #include "src/code-stubs.h"
 #include "src/hydrogen-osr.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
 #include "src/mips/lithium-codegen-mips.h"
 #include "src/mips/lithium-gap-resolver-mips.h"
index 783999f..38b56d2 100644 (file)
@@ -24,6 +24,7 @@
 #include "src/heap/mark-compact.h"
 #include "src/heap/objects-visiting-inl.h"
 #include "src/hydrogen.h"
+#include "src/ic/ic.h"
 #include "src/isolate-inl.h"
 #include "src/log.h"
 #include "src/lookup.h"
@@ -10849,9 +10850,9 @@ void Code::Disassemble(const char* name, OStream& os) {  // NOLINT
     if (is_compare_ic_stub()) {
       DCHECK(CodeStub::GetMajorKey(this) == CodeStub::CompareIC);
       CompareICStub stub(stub_key(), GetIsolate());
-      os << "compare_state = " << CompareIC::GetStateName(stub.left()) << "*"
-         << CompareIC::GetStateName(stub.right()) << " -> "
-         << CompareIC::GetStateName(stub.state()) << "\n";
+      os << "compare_state = " << CompareICState::GetStateName(stub.left())
+         << "*" << CompareICState::GetStateName(stub.right()) << " -> "
+         << CompareICState::GetStateName(stub.state()) << "\n";
       os << "compare_operation = " << Token::Name(stub.op()) << "\n";
     }
   }
index da993a1..f606ce2 100644 (file)
@@ -7,6 +7,7 @@
 #include "src/ast.h"
 #include "src/code-stubs.h"
 #include "src/compiler.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
 #include "src/macro-assembler.h"
 #include "src/type-info.h"
@@ -196,9 +197,9 @@ void TypeFeedbackOracle::CompareType(TypeFeedbackId id,
 
   if (code->is_compare_ic_stub()) {
     CompareICStub stub(code->stub_key(), isolate());
-    *left_type = CompareIC::StateToType(zone(), stub.left());
-    *right_type = CompareIC::StateToType(zone(), stub.right());
-    *combined_type = CompareIC::StateToType(zone(), stub.state(), map);
+    *left_type = CompareICState::StateToType(zone(), stub.left());
+    *right_type = CompareICState::StateToType(zone(), stub.right());
+    *combined_type = CompareICState::StateToType(zone(), stub.state(), map);
   } else if (code->is_compare_nil_ic_stub()) {
     CompareNilICStub stub(isolate(), code->extra_ic_state());
     *combined_type = stub.GetType(zone(), map);
@@ -218,8 +219,8 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
   if (!object->IsCode()) {
     // For some binary ops we don't have ICs, e.g. Token::COMMA, but for the
     // operations covered by the BinaryOpIC we should always have them.
-    DCHECK(op < BinaryOpIC::State::FIRST_TOKEN ||
-           op > BinaryOpIC::State::LAST_TOKEN);
+    DCHECK(op < BinaryOpICState::FIRST_TOKEN ||
+           op > BinaryOpICState::LAST_TOKEN);
     *left = *right = *result = Type::None(zone());
     *fixed_right_arg = Maybe<int>();
     *allocation_site = Handle<AllocationSite>::null();
@@ -227,7 +228,7 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
   }
   Handle<Code> code = Handle<Code>::cast(object);
   DCHECK_EQ(Code::BINARY_OP_IC, code->kind());
-  BinaryOpIC::State state(isolate(), code->extra_ic_state());
+  BinaryOpICState state(isolate(), code->extra_ic_state());
   DCHECK_EQ(op, state.op());
 
   *left = state.GetLeftType(zone());
@@ -249,7 +250,7 @@ Type* TypeFeedbackOracle::CountType(TypeFeedbackId id) {
   if (!object->IsCode()) return Type::None(zone());
   Handle<Code> code = Handle<Code>::cast(object);
   DCHECK_EQ(Code::BINARY_OP_IC, code->kind());
-  BinaryOpIC::State state(isolate(), code->extra_ic_state());
+  BinaryOpICState state(isolate(), code->extra_ic_state());
   return state.GetLeftType(zone());
 }
 
index dfa74e0..a2b172f 100644 (file)
@@ -10,6 +10,7 @@
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
@@ -1389,14 +1390,12 @@ static int NegativeComparisonResult(Condition cc) {
 }
 
 
-static void CheckInputType(MacroAssembler* masm,
-                           Register input,
-                           CompareIC::State expected,
-                           Label* fail) {
+static void CheckInputType(MacroAssembler* masm, Register input,
+                           CompareICState::State expected, Label* fail) {
   Label ok;
-  if (expected == CompareIC::SMI) {
+  if (expected == CompareICState::SMI) {
     __ JumpIfNotSmi(input, fail);
-  } else if (expected == CompareIC::NUMBER) {
+  } else if (expected == CompareICState::NUMBER) {
     __ JumpIfSmi(input, &ok);
     __ CompareMap(input, masm->isolate()->factory()->heap_number_map());
     __ j(not_equal, fail);
@@ -2010,7 +2009,7 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
   __ TailCallStub(&stub);
 
   __ bind(&miss);
-  GenerateMiss(masm, IC::kCallIC_Customization_Miss);
+  GenerateMiss(masm);
 
   // The slow case, we need this no matter what to complete a call after a miss.
   CallFunctionNoFeedback(masm,
@@ -2091,7 +2090,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
 
   // We are here because tracing is on or we are going monomorphic.
   __ bind(&miss);
-  GenerateMiss(masm, IC::kCallIC_Miss);
+  GenerateMiss(masm);
 
   // the slow case
   __ bind(&slow_start);
@@ -2107,7 +2106,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
 }
 
 
-void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
+void CallICStub::GenerateMiss(MacroAssembler* masm) {
   // Get the receiver of the function from the stack; 1 ~ return address.
   __ movp(rcx, Operand(rsp, (arg_count() + 1) * kPointerSize));
 
@@ -2122,6 +2121,9 @@ void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
     __ Push(rdx);
 
     // Call the entry.
+    IC::UtilityId id = GetICState() == DEFAULT ? IC::kCallIC_Miss
+                                               : IC::kCallIC_Customization_Miss;
+
     ExternalReference miss = ExternalReference(IC_Utility(id),
                                                masm->isolate());
     __ CallExternalReference(miss, 4);
@@ -3257,7 +3259,7 @@ void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateSmis(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::SMI);
+  DCHECK(state() == CompareICState::SMI);
   Label miss;
   __ JumpIfNotBothSmi(rdx, rax, &miss, Label::kNear);
 
@@ -3281,16 +3283,16 @@ void CompareICStub::GenerateSmis(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::NUMBER);
+  DCHECK(state() == CompareICState::NUMBER);
 
   Label generic_stub;
   Label unordered, maybe_undefined1, maybe_undefined2;
   Label miss;
 
-  if (left() == CompareIC::SMI) {
+  if (left() == CompareICState::SMI) {
     __ JumpIfNotSmi(rdx, &miss);
   }
-  if (right() == CompareIC::SMI) {
+  if (right() == CompareICState::SMI) {
     __ JumpIfNotSmi(rax, &miss);
   }
 
@@ -3332,8 +3334,8 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
 
   __ bind(&unordered);
   __ bind(&generic_stub);
-  CompareICStub stub(isolate(), op(), CompareIC::GENERIC, CompareIC::GENERIC,
-                     CompareIC::GENERIC);
+  CompareICStub stub(isolate(), op(), CompareICState::GENERIC,
+                     CompareICState::GENERIC, CompareICState::GENERIC);
   __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
 
   __ bind(&maybe_undefined1);
@@ -3358,7 +3360,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::INTERNALIZED_STRING);
+  DCHECK(state() == CompareICState::INTERNALIZED_STRING);
   DCHECK(GetCondition() == equal);
 
   // Registers containing left and right operands respectively.
@@ -3401,7 +3403,7 @@ void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::UNIQUE_NAME);
+  DCHECK(state() == CompareICState::UNIQUE_NAME);
   DCHECK(GetCondition() == equal);
 
   // Registers containing left and right operands respectively.
@@ -3444,7 +3446,7 @@ void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateStrings(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::STRING);
+  DCHECK(state() == CompareICState::STRING);
   Label miss;
 
   bool equality = Token::IsEqualityOp(op());
@@ -3531,7 +3533,7 @@ void CompareICStub::GenerateStrings(MacroAssembler* masm) {
 
 
 void CompareICStub::GenerateObjects(MacroAssembler* masm) {
-  DCHECK(state() == CompareIC::OBJECT);
+  DCHECK(state() == CompareICState::OBJECT);
   Label miss;
   Condition either_smi = masm->CheckEitherSmi(rdx, rax);
   __ j(either_smi, &miss, Label::kNear);
index 0633cdf..a772522 100644 (file)
@@ -12,6 +12,7 @@
 #include "src/compiler.h"
 #include "src/debug.h"
 #include "src/full-codegen.h"
+#include "src/ic/ic.h"
 #include "src/isolate-inl.h"
 #include "src/parser.h"
 #include "src/scopes.h"
@@ -2540,11 +2541,10 @@ void FullCodeGenerator::CallIC(Handle<Code> code,
 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
   Expression* callee = expr->expression();
 
-  CallIC::CallType call_type = callee->IsVariableProxy()
-      ? CallIC::FUNCTION
-      : CallIC::METHOD;
+  CallICState::CallType call_type =
+      callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD;
   // Get the target function.
-  if (call_type == CallIC::FUNCTION) {
+  if (call_type == CallICState::FUNCTION) {
     { StackValueContext context(this);
       EmitVariableLoad(callee->AsVariableProxy());
       PrepareForBailout(callee, NO_REGISTERS);
@@ -2586,11 +2586,11 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
   __ Push(Operand(rsp, 0));
   __ movp(Operand(rsp, kPointerSize), rax);
 
-  EmitCall(expr, CallIC::METHOD);
+  EmitCall(expr, CallICState::METHOD);
 }
 
 
-void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) {
+void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Load the arguments.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
index 80f9fcc..85437a3 100644 (file)
@@ -10,6 +10,7 @@
 #include "src/code-factory.h"
 #include "src/code-stubs.h"
 #include "src/hydrogen-osr.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
 #include "src/x64/lithium-codegen-x64.h"
 
index c864a28..e7fdcd5 100644 (file)
         '../../src/ic/handler-compiler.cc',
         '../../src/ic/handler-compiler.h',
         '../../src/ic/ic-inl.h',
+        '../../src/ic/ic-state.cc',
+        '../../src/ic/ic-state.h',
         '../../src/ic/ic.cc',
         '../../src/ic/ic.h',
         '../../src/ic/ic-compiler.cc',