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.