Revision: 23320
Author:   [email protected]
Date:     Fri Aug 22 14:36:54 2014 UTC
Log: Move PropertyAccessCompiler and CallOptimization to their own files

BUG=
[email protected]

Review URL: https://codereview.chromium.org/480413008
https://code.google.com/p/v8/source/detail?r=23320

Added:
 /branches/bleeding_edge/src/ic/access-compiler.cc
 /branches/bleeding_edge/src/ic/access-compiler.h
 /branches/bleeding_edge/src/ic/arm/access-compiler-arm.cc
 /branches/bleeding_edge/src/ic/arm64/access-compiler-arm64.cc
 /branches/bleeding_edge/src/ic/call-optimization.cc
 /branches/bleeding_edge/src/ic/call-optimization.h
 /branches/bleeding_edge/src/ic/ia32/access-compiler-ia32.cc
 /branches/bleeding_edge/src/ic/x64/access-compiler-x64.cc
Modified:
 /branches/bleeding_edge/BUILD.gn
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ic/arm/ic-compiler-arm.cc
 /branches/bleeding_edge/src/ic/arm64/ic-compiler-arm64.cc
 /branches/bleeding_edge/src/ic/ia32/ic-compiler-ia32.cc
 /branches/bleeding_edge/src/ic/ic-compiler.cc
 /branches/bleeding_edge/src/ic/ic-compiler.h
 /branches/bleeding_edge/src/ic/ic.cc
 /branches/bleeding_edge/src/ic/x64/ic-compiler-x64.cc
 /branches/bleeding_edge/tools/gyp/v8.gyp

=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/ic/access-compiler.cc Fri Aug 22 14:36:54 2014 UTC
@@ -0,0 +1,55 @@
+// 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/access-compiler.h"
+
+
+namespace v8 {
+namespace internal {
+
+
+Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
+                                                      const char* name) {
+  // Create code object in the heap.
+  CodeDesc desc;
+  masm()->GetCode(&desc);
+ Handle<Code> code = factory()->NewCode(desc, flags, masm()->CodeObject());
+  if (code->IsCodeStubOrIC()) code->set_stub_key(CodeStub::NoCacheKey());
+#ifdef ENABLE_DISASSEMBLER
+  if (FLAG_print_code_stubs) {
+    OFStream os(stdout);
+    code->Disassemble(name, os);
+  }
+#endif
+  return code;
+}
+
+
+Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
+                                                      Handle<Name> name) {
+  return (FLAG_print_code_stubs && !name.is_null() && name->IsString())
+             ? GetCodeWithFlags(flags,
+ Handle<String>::cast(name)->ToCString().get())
+             : GetCodeWithFlags(flags, NULL);
+}
+
+
+void PropertyAccessCompiler::TailCallBuiltin(MacroAssembler* masm,
+                                             Builtins::Name name) {
+  Handle<Code> code(masm->isolate()->builtins()->builtin(name));
+  GenerateTailCall(masm, code);
+}
+
+
+Register* PropertyAccessCompiler::GetCallingConvention(Code::Kind kind) {
+  if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC) {
+    return load_calling_convention();
+  }
+  DCHECK(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
+  return store_calling_convention();
+}
+}
+}  // namespace v8::internal
=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/ic/access-compiler.h Fri Aug 22 14:36:54 2014 UTC
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef V8_IC_ACCESS_COMPILER_H_
+#define V8_IC_ACCESS_COMPILER_H_
+
+#include "src/code-stubs.h"
+#include "src/macro-assembler.h"
+#include "src/objects.h"
+
+namespace v8 {
+namespace internal {
+
+
+class PropertyAccessCompiler BASE_EMBEDDED {
+ public:
+  static Builtins::Name MissBuiltin(Code::Kind kind) {
+    switch (kind) {
+      case Code::LOAD_IC:
+        return Builtins::kLoadIC_Miss;
+      case Code::STORE_IC:
+        return Builtins::kStoreIC_Miss;
+      case Code::KEYED_LOAD_IC:
+        return Builtins::kKeyedLoadIC_Miss;
+      case Code::KEYED_STORE_IC:
+        return Builtins::kKeyedStoreIC_Miss;
+      default:
+        UNREACHABLE();
+    }
+    return Builtins::kLoadIC_Miss;
+  }
+
+  static void TailCallBuiltin(MacroAssembler* masm, Builtins::Name name);
+
+ protected:
+  PropertyAccessCompiler(Isolate* isolate, Code::Kind kind,
+                         CacheHolderFlag cache_holder)
+      : registers_(GetCallingConvention(kind)),
+        kind_(kind),
+        cache_holder_(cache_holder),
+        isolate_(isolate),
+        masm_(isolate, NULL, 256) {}
+
+  Code::Kind kind() const { return kind_; }
+  CacheHolderFlag cache_holder() const { return cache_holder_; }
+  MacroAssembler* masm() { return &masm_; }
+  Isolate* isolate() const { return isolate_; }
+  Heap* heap() const { return isolate()->heap(); }
+  Factory* factory() const { return isolate()->factory(); }
+
+  Register receiver() const { return registers_[0]; }
+  Register name() const { return registers_[1]; }
+  Register scratch1() const { return registers_[2]; }
+  Register scratch2() const { return registers_[3]; }
+  Register scratch3() const { return registers_[4]; }
+
+  // Calling convention between indexed store IC and handler.
+  Register transition_map() const { return scratch1(); }
+
+  static Register* GetCallingConvention(Code::Kind);
+  static Register* load_calling_convention();
+  static Register* store_calling_convention();
+  static Register* keyed_store_calling_convention();
+
+  Register* registers_;
+
+  static void GenerateTailCall(MacroAssembler* masm, Handle<Code> code);
+
+  Handle<Code> GetCodeWithFlags(Code::Flags flags, const char* name);
+  Handle<Code> GetCodeWithFlags(Code::Flags flags, Handle<Name> name);
+
+ private:
+  Code::Kind kind_;
+  CacheHolderFlag cache_holder_;
+
+  Isolate* isolate_;
+  MacroAssembler masm_;
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_IC_ACCESS_COMPILER_H_
=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/ic/arm/access-compiler-arm.cc Fri Aug 22 14:36:54 2014 UTC
@@ -0,0 +1,46 @@
+// 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"
+
+#if V8_TARGET_ARCH_ARM
+
+#include "src/ic/access-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
+                                              Handle<Code> code) {
+  __ Jump(code, RelocInfo::CODE_TARGET);
+}
+
+
+Register* PropertyAccessCompiler::load_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3, scratch4.
+  Register receiver = LoadIC::ReceiverRegister();
+  Register name = LoadIC::NameRegister();
+  static Register registers[] = {receiver, name, r3, r0, r4, r5};
+  return registers;
+}
+
+
+Register* PropertyAccessCompiler::store_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3.
+  Register receiver = StoreIC::ReceiverRegister();
+  Register name = StoreIC::NameRegister();
+  DCHECK(r3.is(KeyedStoreIC::MapRegister()));
+  static Register registers[] = {receiver, name, r3, r4, r5};
+  return registers;
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_IA32
=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/ic/arm64/access-compiler-arm64.cc Fri Aug 22 14:36:54 2014 UTC
@@ -0,0 +1,53 @@
+// 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"
+
+#if V8_TARGET_ARCH_ARM64
+
+#include "src/ic/access-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
+                                              Handle<Code> code) {
+  __ Jump(code, RelocInfo::CODE_TARGET);
+}
+
+
+// TODO(all): The so-called scratch registers are significant in some cases. For +// example, PropertyAccessCompiler::keyed_store_calling_convention()[3] (x3) is
+// actually
+// used for KeyedStoreCompiler::transition_map(). We should verify which
+// registers are actually scratch registers, and which are important. For now,
+// we use the same assignments as ARM to remain on the safe side.
+
+Register* PropertyAccessCompiler::load_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3, scratch4.
+  Register receiver = LoadIC::ReceiverRegister();
+  Register name = LoadIC::NameRegister();
+  static Register registers[] = {receiver, name, x3, x0, x4, x5};
+  return registers;
+}
+
+
+Register* PropertyAccessCompiler::store_calling_convention() {
+  // receiver, value, scratch1, scratch2, scratch3.
+  Register receiver = StoreIC::ReceiverRegister();
+  Register name = StoreIC::NameRegister();
+  DCHECK(x3.is(KeyedStoreIC::MapRegister()));
+  static Register registers[] = {receiver, name, x3, x4, x5};
+  return registers;
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_ARM64
=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/ic/call-optimization.cc Fri Aug 22 14:36:54 2014 UTC
@@ -0,0 +1,113 @@
+// 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/call-optimization.h"
+
+
+namespace v8 {
+namespace internal {
+
+CallOptimization::CallOptimization(Handle<JSFunction> function) {
+  Initialize(function);
+}
+
+
+Handle<JSObject> CallOptimization::LookupHolderOfExpectedType(
+    Handle<Map> object_map, HolderLookup* holder_lookup) const {
+  DCHECK(is_simple_api_call());
+  if (!object_map->IsJSObjectMap()) {
+    *holder_lookup = kHolderNotFound;
+    return Handle<JSObject>::null();
+  }
+  if (expected_receiver_type_.is_null() ||
+      expected_receiver_type_->IsTemplateFor(*object_map)) {
+    *holder_lookup = kHolderIsReceiver;
+    return Handle<JSObject>::null();
+  }
+  while (true) {
+    if (!object_map->prototype()->IsJSObject()) break;
+    Handle<JSObject> prototype(JSObject::cast(object_map->prototype()));
+    if (!prototype->map()->is_hidden_prototype()) break;
+    object_map = handle(prototype->map());
+    if (expected_receiver_type_->IsTemplateFor(*object_map)) {
+      *holder_lookup = kHolderFound;
+      return prototype;
+    }
+  }
+  *holder_lookup = kHolderNotFound;
+  return Handle<JSObject>::null();
+}
+
+
+bool CallOptimization::IsCompatibleReceiver(Handle<Object> receiver,
+ Handle<JSObject> holder) const {
+  DCHECK(is_simple_api_call());
+  if (!receiver->IsJSObject()) return false;
+  Handle<Map> map(JSObject::cast(*receiver)->map());
+  HolderLookup holder_lookup;
+ Handle<JSObject> api_holder = LookupHolderOfExpectedType(map, &holder_lookup);
+  switch (holder_lookup) {
+    case kHolderNotFound:
+      return false;
+    case kHolderIsReceiver:
+      return true;
+    case kHolderFound:
+      if (api_holder.is_identical_to(holder)) return true;
+      // Check if holder is in prototype chain of api_holder.
+      {
+        JSObject* object = *api_holder;
+        while (true) {
+          Object* prototype = object->map()->prototype();
+          if (!prototype->IsJSObject()) return false;
+          if (prototype == *holder) return true;
+          object = JSObject::cast(prototype);
+        }
+      }
+      break;
+  }
+  UNREACHABLE();
+  return false;
+}
+
+
+void CallOptimization::Initialize(Handle<JSFunction> function) {
+  constant_function_ = Handle<JSFunction>::null();
+  is_simple_api_call_ = false;
+  expected_receiver_type_ = Handle<FunctionTemplateInfo>::null();
+  api_call_info_ = Handle<CallHandlerInfo>::null();
+
+  if (function.is_null() || !function->is_compiled()) return;
+
+  constant_function_ = function;
+  AnalyzePossibleApiFunction(function);
+}
+
+
+void CallOptimization::AnalyzePossibleApiFunction(Handle<JSFunction> function) {
+  if (!function->shared()->IsApiFunction()) return;
+ Handle<FunctionTemplateInfo> info(function->shared()->get_api_func_data());
+
+  // Require a C++ callback.
+  if (info->call_code()->IsUndefined()) return;
+  api_call_info_ =
+      Handle<CallHandlerInfo>(CallHandlerInfo::cast(info->call_code()));
+
+  // Accept signatures that either have no restrictions at all or
+  // only have restrictions on the receiver.
+  if (!info->signature()->IsUndefined()) {
+    Handle<SignatureInfo> signature =
+        Handle<SignatureInfo>(SignatureInfo::cast(info->signature()));
+    if (!signature->args()->IsUndefined()) return;
+    if (!signature->receiver()->IsUndefined()) {
+      expected_receiver_type_ = Handle<FunctionTemplateInfo>(
+          FunctionTemplateInfo::cast(signature->receiver()));
+    }
+  }
+
+  is_simple_api_call_ = true;
+}
+}
+}  // namespace v8::internal
=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/ic/call-optimization.h Fri Aug 22 14:36:54 2014 UTC
@@ -0,0 +1,62 @@
+// 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.
+
+#ifndef V8_IC_CALL_OPTIMIZATION_H_
+#define V8_IC_CALL_OPTIMIZATION_H_
+
+#include "src/code-stubs.h"
+#include "src/ic/access-compiler.h"
+#include "src/macro-assembler.h"
+#include "src/objects.h"
+
+namespace v8 {
+namespace internal {
+// Holds information about possible function call optimizations.
+class CallOptimization BASE_EMBEDDED {
+ public:
+  explicit CallOptimization(Handle<JSFunction> function);
+
+  bool is_constant_call() const { return !constant_function_.is_null(); }
+
+  Handle<JSFunction> constant_function() const {
+    DCHECK(is_constant_call());
+    return constant_function_;
+  }
+
+  bool is_simple_api_call() const { return is_simple_api_call_; }
+
+  Handle<FunctionTemplateInfo> expected_receiver_type() const {
+    DCHECK(is_simple_api_call());
+    return expected_receiver_type_;
+  }
+
+  Handle<CallHandlerInfo> api_call_info() const {
+    DCHECK(is_simple_api_call());
+    return api_call_info_;
+  }
+
+  enum HolderLookup { kHolderNotFound, kHolderIsReceiver, kHolderFound };
+  Handle<JSObject> LookupHolderOfExpectedType(
+      Handle<Map> receiver_map, HolderLookup* holder_lookup) const;
+
+  // Check if the api holder is between the receiver and the holder.
+  bool IsCompatibleReceiver(Handle<Object> receiver,
+                            Handle<JSObject> holder) const;
+
+ private:
+  void Initialize(Handle<JSFunction> function);
+
+  // Determines whether the given function can be called using the
+  // fast api call builtin.
+  void AnalyzePossibleApiFunction(Handle<JSFunction> function);
+
+  Handle<JSFunction> constant_function_;
+  bool is_simple_api_call_;
+  Handle<FunctionTemplateInfo> expected_receiver_type_;
+  Handle<CallHandlerInfo> api_call_info_;
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_IC_CALL_OPTIMIZATION_H_
=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/ic/ia32/access-compiler-ia32.cc Fri Aug 22 14:36:54 2014 UTC
@@ -0,0 +1,44 @@
+// 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"
+
+#if V8_TARGET_ARCH_IA32
+
+#include "src/ic/access-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
+                                              Handle<Code> code) {
+  __ jmp(code, RelocInfo::CODE_TARGET);
+}
+
+
+Register* PropertyAccessCompiler::load_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3, scratch4.
+  Register receiver = LoadIC::ReceiverRegister();
+  Register name = LoadIC::NameRegister();
+  static Register registers[] = {receiver, name, ebx, eax, edi, no_reg};
+  return registers;
+}
+
+
+Register* PropertyAccessCompiler::store_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3.
+  Register receiver = StoreIC::ReceiverRegister();
+  Register name = StoreIC::NameRegister();
+  DCHECK(ebx.is(KeyedStoreIC::MapRegister()));
+  static Register registers[] = {receiver, name, ebx, edi, no_reg};
+  return registers;
+}
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_IA32
=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/ic/x64/access-compiler-x64.cc Fri Aug 22 14:36:54 2014 UTC
@@ -0,0 +1,46 @@
+// 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"
+
+#if V8_TARGET_ARCH_X64
+
+#include "src/ic/access-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
+                                              Handle<Code> code) {
+  __ jmp(code, RelocInfo::CODE_TARGET);
+}
+
+
+Register* PropertyAccessCompiler::load_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3, scratch4.
+  Register receiver = LoadIC::ReceiverRegister();
+  Register name = LoadIC::NameRegister();
+  static Register registers[] = {receiver, name, rax, rbx, rdi, r8};
+  return registers;
+}
+
+
+Register* PropertyAccessCompiler::store_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3.
+  Register receiver = KeyedStoreIC::ReceiverRegister();
+  Register name = KeyedStoreIC::NameRegister();
+  DCHECK(rbx.is(KeyedStoreIC::MapRegister()));
+  static Register registers[] = {receiver, name, rbx, rdi, r8};
+  return registers;
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_X64
=======================================
--- /branches/bleeding_edge/BUILD.gn    Fri Aug 22 12:30:25 2014 UTC
+++ /branches/bleeding_edge/BUILD.gn    Fri Aug 22 14:36:54 2014 UTC
@@ -714,6 +714,10 @@
     "src/i18n.h",
     "src/icu_util.cc",
     "src/icu_util.h",
+    "src/ic/access-compiler.cc",
+    "src/ic/access-compiler.h",
+    "src/ic/call-optimization.cc",
+    "src/ic/call-optimization.h",
     "src/ic/ic-inl.h",
     "src/ic/ic.cc",
     "src/ic/ic.h",
@@ -929,6 +933,7 @@
       "src/compiler/x64/instruction-codes-x64.h",
       "src/compiler/x64/instruction-selector-x64.cc",
       "src/compiler/x64/linkage-x64.cc",
+      "src/ic/x64/access-compiler-x64.cc",
       "src/ic/x64/ic-x64.cc",
       "src/ic/x64/ic-compiler-x64.cc",
       "src/ic/x64/stub-cache-x64.cc",
@@ -967,6 +972,7 @@
       "src/compiler/arm/instruction-codes-arm.h",
       "src/compiler/arm/instruction-selector-arm.cc",
       "src/compiler/arm/linkage-arm.cc",
+      "src/ic/arm/access-compiler-arm.cc",
       "src/ic/arm/ic-arm.cc",
       "src/ic/arm/ic-compiler-arm.cc",
       "src/ic/arm/stub-cache-arm.cc",
@@ -1016,6 +1022,7 @@
       "src/compiler/arm64/instruction-codes-arm64.h",
       "src/compiler/arm64/instruction-selector-arm64.cc",
       "src/compiler/arm64/linkage-arm64.cc",
+      "src/ic/arm64/access-compiler-arm64.cc",
       "src/ic/arm64/ic-arm64.cc",
       "src/ic/arm64/ic-compiler-arm64.cc",
       "src/ic/arm64/stub-cache-arm64.cc",
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Fri Aug 22 11:43:39 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc     Fri Aug 22 14:36:54 2014 UTC
@@ -34,16 +34,15 @@
 #include "src/hydrogen-sce.h"
 #include "src/hydrogen-store-elimination.h"
 #include "src/hydrogen-uint32-analysis.h"
+#include "src/ic/call-optimization.h"
+// GetRootConstructor
+#include "src/ic/ic-inl.h"
 #include "src/lithium-allocator.h"
 #include "src/parser.h"
 #include "src/runtime.h"
 #include "src/scopeinfo.h"
 #include "src/scopes.h"
 #include "src/typing.h"
-// CallOptimization
-#include "src/ic/ic-compiler.h"
-// GetRootConstructor
-#include "src/ic/ic-inl.h"

 #if V8_TARGET_ARCH_IA32
 #include "src/ia32/lithium-codegen-ia32.h"  // NOLINT
=======================================
--- /branches/bleeding_edge/src/ic/arm/ic-compiler-arm.cc Fri Aug 22 12:48:15 2014 UTC +++ /branches/bleeding_edge/src/ic/arm/ic-compiler-arm.cc Fri Aug 22 14:36:54 2014 UTC
@@ -6,6 +6,7 @@

 #if V8_TARGET_ARCH_ARM

+#include "src/ic/call-optimization.h"
 #include "src/ic/ic-compiler.h"

 namespace v8 {
@@ -207,12 +208,6 @@
   CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
   __ TailCallStub(&stub);
 }
-
-
-void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
-                                              Handle<Code> code) {
-  __ Jump(code, RelocInfo::CODE_TARGET);
-}


 #undef __
@@ -749,25 +744,6 @@
   // Return the generated code.
   return GetCode(kind(), Code::FAST, name);
 }
-
-
-Register* PropertyAccessCompiler::load_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3, scratch4.
-  Register receiver = LoadIC::ReceiverRegister();
-  Register name = LoadIC::NameRegister();
-  static Register registers[] = {receiver, name, r3, r0, r4, r5};
-  return registers;
-}
-
-
-Register* PropertyAccessCompiler::store_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3.
-  Register receiver = StoreIC::ReceiverRegister();
-  Register name = StoreIC::NameRegister();
-  DCHECK(r3.is(KeyedStoreIC::MapRegister()));
-  static Register registers[] = {receiver, name, r3, r4, r5};
-  return registers;
-}


Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
=======================================
--- /branches/bleeding_edge/src/ic/arm64/ic-compiler-arm64.cc Fri Aug 22 12:48:15 2014 UTC +++ /branches/bleeding_edge/src/ic/arm64/ic-compiler-arm64.cc Fri Aug 22 14:36:54 2014 UTC
@@ -6,6 +6,7 @@

 #if V8_TARGET_ARCH_ARM64

+#include "src/ic/call-optimization.h"
 #include "src/ic/ic-compiler.h"

 namespace v8 {
@@ -203,12 +204,6 @@
   CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
   __ TailCallStub(&stub);
 }
-
-
-void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
-                                              Handle<Code> code) {
-  __ Jump(code, RelocInfo::CODE_TARGET);
-}


 #undef __
@@ -761,32 +756,6 @@
   // Return the generated code.
   return GetCode(kind(), Code::FAST, name);
 }
-
-
-// TODO(all): The so-called scratch registers are significant in some cases. For -// example, PropertyAccessCompiler::keyed_store_calling_convention()[3] (x3) is
-// actually
-// used for KeyedStoreCompiler::transition_map(). We should verify which
-// registers are actually scratch registers, and which are important. For now,
-// we use the same assignments as ARM to remain on the safe side.
-
-Register* PropertyAccessCompiler::load_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3, scratch4.
-  Register receiver = LoadIC::ReceiverRegister();
-  Register name = LoadIC::NameRegister();
-  static Register registers[] = {receiver, name, x3, x0, x4, x5};
-  return registers;
-}
-
-
-Register* PropertyAccessCompiler::store_calling_convention() {
-  // receiver, value, scratch1, scratch2, scratch3.
-  Register receiver = StoreIC::ReceiverRegister();
-  Register name = StoreIC::NameRegister();
-  DCHECK(x3.is(KeyedStoreIC::MapRegister()));
-  static Register registers[] = {receiver, name, x3, x4, x5};
-  return registers;
-}


Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
=======================================
--- /branches/bleeding_edge/src/ic/ia32/ic-compiler-ia32.cc Fri Aug 22 12:48:15 2014 UTC +++ /branches/bleeding_edge/src/ic/ia32/ic-compiler-ia32.cc Fri Aug 22 14:36:54 2014 UTC
@@ -6,6 +6,7 @@

 #if V8_TARGET_ARCH_IA32

+#include "src/ic/call-optimization.h"
 #include "src/ic/ic-compiler.h"

 namespace v8 {
@@ -204,12 +205,6 @@
   }
   __ j(not_equal, miss);
 }
-
-
-void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
-                                              Handle<Code> code) {
-  __ jmp(code, RelocInfo::CODE_TARGET);
-}


 #undef __
@@ -776,25 +771,6 @@
   // Return the generated code.
return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
-
-
-Register* PropertyAccessCompiler::load_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3, scratch4.
-  Register receiver = LoadIC::ReceiverRegister();
-  Register name = LoadIC::NameRegister();
-  static Register registers[] = {receiver, name, ebx, eax, edi, no_reg};
-  return registers;
-}
-
-
-Register* PropertyAccessCompiler::store_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3.
-  Register receiver = StoreIC::ReceiverRegister();
-  Register name = StoreIC::NameRegister();
-  DCHECK(ebx.is(KeyedStoreIC::MapRegister()));
-  static Register registers[] = {receiver, name, ebx, edi, no_reg};
-  return registers;
-}


Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
=======================================
--- /branches/bleeding_edge/src/ic/ic-compiler.cc Fri Aug 22 12:48:15 2014 UTC +++ /branches/bleeding_edge/src/ic/ic-compiler.cc Fri Aug 22 14:36:54 2014 UTC
@@ -4,6 +4,7 @@

 #include "src/v8.h"

+#include "src/ic/call-optimization.h"
 #include "src/ic/ic-inl.h"
 #include "src/ic/ic-compiler.h"

@@ -176,9 +177,6 @@
          store_mode);
   return code;
 }
-
-
-#define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type)


Code* PropertyICCompiler::FindPreMonomorphic(Isolate* isolate, Code::Kind kind,
@@ -400,35 +398,6 @@
PROFILE(isolate(), CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0));
   return code;
 }
-
-
-#undef CALL_LOGGER_TAG
-
-
-Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
-                                                      const char* name) {
-  // Create code object in the heap.
-  CodeDesc desc;
-  masm()->GetCode(&desc);
- Handle<Code> code = factory()->NewCode(desc, flags, masm()->CodeObject());
-  if (code->IsCodeStubOrIC()) code->set_stub_key(CodeStub::NoCacheKey());
-#ifdef ENABLE_DISASSEMBLER
-  if (FLAG_print_code_stubs) {
-    OFStream os(stdout);
-    code->Disassemble(name, os);
-  }
-#endif
-  return code;
-}
-
-
-Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
-                                                      Handle<Name> name) {
-  return (FLAG_print_code_stubs && !name.is_null() && name->IsString())
-             ? GetCodeWithFlags(flags,
- Handle<String>::cast(name)->ToCString().get())
-             : GetCodeWithFlags(flags, NULL);
-}


 #define __ ACCESS_MASM(masm())
@@ -753,22 +722,6 @@


 #undef __
-
-
-void PropertyAccessCompiler::TailCallBuiltin(MacroAssembler* masm,
-                                             Builtins::Name name) {
-  Handle<Code> code(masm->isolate()->builtins()->builtin(name));
-  GenerateTailCall(masm, code);
-}
-
-
-Register* PropertyAccessCompiler::GetCallingConvention(Code::Kind kind) {
-  if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC) {
-    return load_calling_convention();
-  }
-  DCHECK(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
-  return store_calling_convention();
-}


Handle<Code> PropertyICCompiler::GetCode(Code::Kind kind, Code::StubType type,
@@ -880,104 +833,5 @@
 }


-CallOptimization::CallOptimization(Handle<JSFunction> function) {
-  Initialize(function);
-}
-
-
-Handle<JSObject> CallOptimization::LookupHolderOfExpectedType(
-    Handle<Map> object_map, HolderLookup* holder_lookup) const {
-  DCHECK(is_simple_api_call());
-  if (!object_map->IsJSObjectMap()) {
-    *holder_lookup = kHolderNotFound;
-    return Handle<JSObject>::null();
-  }
-  if (expected_receiver_type_.is_null() ||
-      expected_receiver_type_->IsTemplateFor(*object_map)) {
-    *holder_lookup = kHolderIsReceiver;
-    return Handle<JSObject>::null();
-  }
-  while (true) {
-    if (!object_map->prototype()->IsJSObject()) break;
-    Handle<JSObject> prototype(JSObject::cast(object_map->prototype()));
-    if (!prototype->map()->is_hidden_prototype()) break;
-    object_map = handle(prototype->map());
-    if (expected_receiver_type_->IsTemplateFor(*object_map)) {
-      *holder_lookup = kHolderFound;
-      return prototype;
-    }
-  }
-  *holder_lookup = kHolderNotFound;
-  return Handle<JSObject>::null();
-}
-
-
-bool CallOptimization::IsCompatibleReceiver(Handle<Object> receiver,
- Handle<JSObject> holder) const {
-  DCHECK(is_simple_api_call());
-  if (!receiver->IsJSObject()) return false;
-  Handle<Map> map(JSObject::cast(*receiver)->map());
-  HolderLookup holder_lookup;
- Handle<JSObject> api_holder = LookupHolderOfExpectedType(map, &holder_lookup);
-  switch (holder_lookup) {
-    case kHolderNotFound:
-      return false;
-    case kHolderIsReceiver:
-      return true;
-    case kHolderFound:
-      if (api_holder.is_identical_to(holder)) return true;
-      // Check if holder is in prototype chain of api_holder.
-      {
-        JSObject* object = *api_holder;
-        while (true) {
-          Object* prototype = object->map()->prototype();
-          if (!prototype->IsJSObject()) return false;
-          if (prototype == *holder) return true;
-          object = JSObject::cast(prototype);
-        }
-      }
-      break;
-  }
-  UNREACHABLE();
-  return false;
-}
-
-
-void CallOptimization::Initialize(Handle<JSFunction> function) {
-  constant_function_ = Handle<JSFunction>::null();
-  is_simple_api_call_ = false;
-  expected_receiver_type_ = Handle<FunctionTemplateInfo>::null();
-  api_call_info_ = Handle<CallHandlerInfo>::null();
-
-  if (function.is_null() || !function->is_compiled()) return;
-
-  constant_function_ = function;
-  AnalyzePossibleApiFunction(function);
-}
-
-
-void CallOptimization::AnalyzePossibleApiFunction(Handle<JSFunction> function) {
-  if (!function->shared()->IsApiFunction()) return;
- Handle<FunctionTemplateInfo> info(function->shared()->get_api_func_data());
-
-  // Require a C++ callback.
-  if (info->call_code()->IsUndefined()) return;
-  api_call_info_ =
-      Handle<CallHandlerInfo>(CallHandlerInfo::cast(info->call_code()));
-
-  // Accept signatures that either have no restrictions at all or
-  // only have restrictions on the receiver.
-  if (!info->signature()->IsUndefined()) {
-    Handle<SignatureInfo> signature =
-        Handle<SignatureInfo>(SignatureInfo::cast(info->signature()));
-    if (!signature->args()->IsUndefined()) return;
-    if (!signature->receiver()->IsUndefined()) {
-      expected_receiver_type_ = Handle<FunctionTemplateInfo>(
-          FunctionTemplateInfo::cast(signature->receiver()));
-    }
-  }
-
-  is_simple_api_call_ = true;
-}
 }
 }  // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/ic/ic-compiler.h Fri Aug 22 12:48:15 2014 UTC +++ /branches/bleeding_edge/src/ic/ic-compiler.h Fri Aug 22 14:36:54 2014 UTC
@@ -6,6 +6,7 @@
 #define V8_IC_IC_COMPILER_H_

 #include "src/code-stubs.h"
+#include "src/ic/access-compiler.h"
 #include "src/macro-assembler.h"
 #include "src/objects.h"

@@ -14,80 +15,12 @@


 class CallOptimization;
-class SmallMapList;
-class StubCache;


 enum PrototypeCheckType { CHECK_ALL_MAPS, SKIP_RECEIVER };
 enum IcCheckType { ELEMENT, PROPERTY };


-class PropertyAccessCompiler BASE_EMBEDDED {
- public:
-  static Builtins::Name MissBuiltin(Code::Kind kind) {
-    switch (kind) {
-      case Code::LOAD_IC:
-        return Builtins::kLoadIC_Miss;
-      case Code::STORE_IC:
-        return Builtins::kStoreIC_Miss;
-      case Code::KEYED_LOAD_IC:
-        return Builtins::kKeyedLoadIC_Miss;
-      case Code::KEYED_STORE_IC:
-        return Builtins::kKeyedStoreIC_Miss;
-      default:
-        UNREACHABLE();
-    }
-    return Builtins::kLoadIC_Miss;
-  }
-
-  static void TailCallBuiltin(MacroAssembler* masm, Builtins::Name name);
-
- protected:
-  PropertyAccessCompiler(Isolate* isolate, Code::Kind kind,
-                         CacheHolderFlag cache_holder)
-      : registers_(GetCallingConvention(kind)),
-        kind_(kind),
-        cache_holder_(cache_holder),
-        isolate_(isolate),
-        masm_(isolate, NULL, 256) {}
-
-  Code::Kind kind() const { return kind_; }
-  CacheHolderFlag cache_holder() const { return cache_holder_; }
-  MacroAssembler* masm() { return &masm_; }
-  Isolate* isolate() const { return isolate_; }
-  Heap* heap() const { return isolate()->heap(); }
-  Factory* factory() const { return isolate()->factory(); }
-
-  Register receiver() const { return registers_[0]; }
-  Register name() const { return registers_[1]; }
-  Register scratch1() const { return registers_[2]; }
-  Register scratch2() const { return registers_[3]; }
-  Register scratch3() const { return registers_[4]; }
-
-  // Calling convention between indexed store IC and handler.
-  Register transition_map() const { return scratch1(); }
-
-  static Register* GetCallingConvention(Code::Kind);
-  static Register* load_calling_convention();
-  static Register* store_calling_convention();
-  static Register* keyed_store_calling_convention();
-
-  Register* registers_;
-
-  static void GenerateTailCall(MacroAssembler* masm, Handle<Code> code);
-
-  Handle<Code> GetCodeWithFlags(Code::Flags flags, const char* name);
-  Handle<Code> GetCodeWithFlags(Code::Flags flags, Handle<Name> name);
-
- private:
-  Code::Kind kind_;
-  CacheHolderFlag cache_holder_;
-
-  Isolate* isolate_;
-  MacroAssembler masm_;
-};
-
-
 class PropertyICCompiler : public PropertyAccessCompiler {
  public:
   // Finds the Code object stored in the Heap::non_monomorphic_cache().
@@ -450,51 +383,7 @@
   static void GenerateStoreDictionaryElement(MacroAssembler* masm);
 };

-
-// Holds information about possible function call optimizations.
-class CallOptimization BASE_EMBEDDED {
- public:
-  explicit CallOptimization(Handle<JSFunction> function);
-
-  bool is_constant_call() const { return !constant_function_.is_null(); }
-
-  Handle<JSFunction> constant_function() const {
-    DCHECK(is_constant_call());
-    return constant_function_;
-  }
-
-  bool is_simple_api_call() const { return is_simple_api_call_; }
-
-  Handle<FunctionTemplateInfo> expected_receiver_type() const {
-    DCHECK(is_simple_api_call());
-    return expected_receiver_type_;
-  }
-
-  Handle<CallHandlerInfo> api_call_info() const {
-    DCHECK(is_simple_api_call());
-    return api_call_info_;
-  }
-
-  enum HolderLookup { kHolderNotFound, kHolderIsReceiver, kHolderFound };
-  Handle<JSObject> LookupHolderOfExpectedType(
-      Handle<Map> receiver_map, HolderLookup* holder_lookup) const;
-
-  // Check if the api holder is between the receiver and the holder.
-  bool IsCompatibleReceiver(Handle<Object> receiver,
-                            Handle<JSObject> holder) const;
-
- private:
-  void Initialize(Handle<JSFunction> function);
-
-  // Determines whether the given function can be called using the
-  // fast api call builtin.
-  void AnalyzePossibleApiFunction(Handle<JSFunction> function);

-  Handle<JSFunction> constant_function_;
-  bool is_simple_api_call_;
-  Handle<FunctionTemplateInfo> expected_receiver_type_;
-  Handle<CallHandlerInfo> api_call_info_;
-};
 }
 }  // namespace v8::internal

=======================================
--- /branches/bleeding_edge/src/ic/ic.cc        Fri Aug 22 11:43:39 2014 UTC
+++ /branches/bleeding_edge/src/ic/ic.cc        Fri Aug 22 14:36:54 2014 UTC
@@ -10,6 +10,7 @@
 #include "src/codegen.h"
 #include "src/conversions.h"
 #include "src/execution.h"
+#include "src/ic/call-optimization.h"
 #include "src/ic/ic-inl.h"
 #include "src/ic/ic-compiler.h"
 #include "src/ic/stub-cache.h"
=======================================
--- /branches/bleeding_edge/src/ic/x64/ic-compiler-x64.cc Fri Aug 22 12:48:15 2014 UTC +++ /branches/bleeding_edge/src/ic/x64/ic-compiler-x64.cc Fri Aug 22 14:36:54 2014 UTC
@@ -6,6 +6,7 @@

 #if V8_TARGET_ARCH_X64

+#include "src/ic/call-optimization.h"
 #include "src/ic/ic-compiler.h"

 namespace v8 {
@@ -196,12 +197,6 @@
          masm->isolate()->factory()->the_hole_value());
   __ j(not_equal, miss);
 }
-
-
-void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
-                                              Handle<Code> code) {
-  __ jmp(code, RelocInfo::CODE_TARGET);
-}


 #undef __
@@ -766,25 +761,6 @@
   // Return the generated code.
return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
-
-
-Register* PropertyAccessCompiler::load_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3, scratch4.
-  Register receiver = LoadIC::ReceiverRegister();
-  Register name = LoadIC::NameRegister();
-  static Register registers[] = {receiver, name, rax, rbx, rdi, r8};
-  return registers;
-}
-
-
-Register* PropertyAccessCompiler::store_calling_convention() {
-  // receiver, name, scratch1, scratch2, scratch3.
-  Register receiver = KeyedStoreIC::ReceiverRegister();
-  Register name = KeyedStoreIC::NameRegister();
-  DCHECK(rbx.is(KeyedStoreIC::MapRegister()));
-  static Register registers[] = {receiver, name, rbx, rdi, r8};
-  return registers;
-}


Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
=======================================
--- /branches/bleeding_edge/tools/gyp/v8.gyp    Fri Aug 22 11:43:39 2014 UTC
+++ /branches/bleeding_edge/tools/gyp/v8.gyp    Fri Aug 22 14:36:54 2014 UTC
@@ -599,6 +599,10 @@
         '../../src/i18n.h',
         '../../src/icu_util.cc',
         '../../src/icu_util.h',
+        '../../src/ic/access-compiler.cc',
+        '../../src/ic/access-compiler.h',
+        '../../src/ic/call-optimization.cc',
+        '../../src/ic/call-optimization.h',
         '../../src/ic/ic-inl.h',
         '../../src/ic/ic.cc',
         '../../src/ic/ic.h',
@@ -789,6 +793,7 @@
             '../../src/compiler/arm/instruction-codes-arm.h',
             '../../src/compiler/arm/instruction-selector-arm.cc',
             '../../src/compiler/arm/linkage-arm.cc',
+            '../../src/ic/arm/access-compiler-arm.cc',
             '../../src/ic/arm/ic-arm.cc',
             '../../src/ic/arm/ic-compiler-arm.cc',
             '../../src/ic/arm/stub-cache-arm.cc',
@@ -842,6 +847,7 @@
             '../../src/compiler/arm64/instruction-codes-arm64.h',
             '../../src/compiler/arm64/instruction-selector-arm64.cc',
             '../../src/compiler/arm64/linkage-arm64.cc',
+            '../../src/ic/arm64/access-compiler-arm64.cc',
             '../../src/ic/arm64/ic-arm64.cc',
             '../../src/ic/arm64/ic-compiler-arm64.cc',
             '../../src/ic/arm64/stub-cache-arm64.cc',
@@ -878,6 +884,7 @@
             '../../src/compiler/ia32/instruction-codes-ia32.h',
             '../../src/compiler/ia32/instruction-selector-ia32.cc',
             '../../src/compiler/ia32/linkage-ia32.cc',
+            '../../src/ic/ia32/access-compiler-ia32.cc',
             '../../src/ic/ia32/ic-ia32.cc',
             '../../src/ic/ia32/ic-compiler-ia32.cc',
             '../../src/ic/ia32/stub-cache-ia32.cc',
@@ -1013,6 +1020,7 @@
             '../../src/compiler/x64/instruction-codes-x64.h',
             '../../src/compiler/x64/instruction-selector-x64.cc',
             '../../src/compiler/x64/linkage-x64.cc',
+            '../../src/ic/x64/access-compiler-x64.cc',
             '../../src/ic/x64/ic-x64.cc',
             '../../src/ic/x64/ic-compiler-x64.cc',
             '../../src/ic/x64/stub-cache-x64.cc',

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to