Commit 3c873c43 authored by verwaest@chromium.org's avatar verwaest@chromium.org

Restructure the IC / Handler compilers

BUG=
R=ishell@chromium.org, mvstanton@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22622 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 553e069f
......@@ -1845,20 +1845,12 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Label miss;
Register receiver = LoadIC::ReceiverRegister();
Register name = LoadIC::NameRegister();
ASSERT(kind() == Code::LOAD_IC ||
kind() == Code::KEYED_LOAD_IC);
if (kind() == Code::KEYED_LOAD_IC) {
__ cmp(name, Operand(isolate()->factory()->prototype_string()));
__ b(ne, &miss);
}
StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, r3, r4, &miss);
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r3,
r4, &miss);
__ bind(&miss);
StubCompiler::TailCallBuiltin(
masm, BaseLoadStoreStubCompiler::MissBuiltin(kind()));
PropertyAccessCompiler::TailCallBuiltin(
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
}
......
This diff is collapsed.
......@@ -1703,21 +1703,13 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Label miss;
Register receiver = LoadIC::ReceiverRegister();
Register name = LoadIC::NameRegister();
ASSERT(kind() == Code::LOAD_IC ||
kind() == Code::KEYED_LOAD_IC);
if (kind() == Code::KEYED_LOAD_IC) {
__ Cmp(name, Operand(isolate()->factory()->prototype_string()));
__ B(ne, &miss);
}
StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, x10, x11, &miss);
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, x10,
x11, &miss);
__ Bind(&miss);
StubCompiler::TailCallBuiltin(masm,
BaseLoadStoreStubCompiler::MissBuiltin(kind()));
PropertyAccessCompiler::TailCallBuiltin(
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
}
......
This diff is collapsed.
......@@ -1313,7 +1313,7 @@ static void Generate_LoadIC_Normal(MacroAssembler* masm) {
static void Generate_LoadIC_Getter_ForDeopt(MacroAssembler* masm) {
LoadStubCompiler::GenerateLoadViaGetterForDeopt(masm);
NamedLoadHandlerCompiler::GenerateLoadViaGetterForDeopt(masm);
}
......@@ -1378,7 +1378,7 @@ static void Generate_StoreIC_Normal(MacroAssembler* masm) {
static void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) {
StoreStubCompiler::GenerateStoreViaSetterForDeopt(masm);
NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm);
}
......
......@@ -236,6 +236,8 @@ const char* CodeStub::MajorName(CodeStub::Major major_key,
CODE_STUB_LIST(DEF_CASE)
#undef DEF_CASE
case UninitializedMajorKey: return "<UninitializedMajorKey>Stub";
case NoCache:
return "<NoCache>Stub";
default:
if (!allow_unknown_keys) {
UNREACHABLE();
......@@ -671,7 +673,7 @@ void StoreGlobalStub::InitializeInterfaceDescriptor(
void KeyedLoadDictionaryElementPlatformStub::Generate(
MacroAssembler* masm) {
KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm);
IndexedHandlerCompiler::GenerateLoadDictionaryElement(masm);
}
......@@ -698,7 +700,7 @@ void KeyedStoreElementStub::Generate(MacroAssembler* masm) {
UNREACHABLE();
break;
case DICTIONARY_ELEMENTS:
KeyedStoreStubCompiler::GenerateStoreDictionaryElement(masm);
IndexedHandlerCompiler::GenerateStoreDictionaryElement(masm);
break;
case SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
......
......@@ -900,23 +900,14 @@ class CallIC_ArrayStub: public CallICStub {
// TODO(verwaest): Translate to hydrogen code stub.
class FunctionPrototypeStub : public PlatformCodeStub {
public:
FunctionPrototypeStub(Isolate* isolate, Code::Kind kind)
: PlatformCodeStub(isolate) {
bit_field_ = KindBits::encode(kind);
}
explicit FunctionPrototypeStub(Isolate* isolate)
: PlatformCodeStub(isolate) {}
virtual void Generate(MacroAssembler* masm);
virtual Code::Kind GetCodeKind() const { return Code::HANDLER; }
virtual InlineCacheState GetICState() { return MONOMORPHIC; }
virtual ExtraICState GetExtraICState() const { return kind(); }
protected:
class KindBits : public BitField<Code::Kind, 0, 4> {};
virtual Code::Kind kind() const { return KindBits::decode(bit_field_); }
private:
virtual CodeStub::Major MajorKey() const { return FunctionPrototype; }
virtual int MinorKey() const { return bit_field_; }
int bit_field_;
virtual int MinorKey() const { return 0; }
};
......
......@@ -885,22 +885,14 @@ void MathPowStub::Generate(MacroAssembler* masm) {
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- ecx : name
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
Label miss;
Register receiver = LoadIC::ReceiverRegister();
if (kind() == Code::KEYED_LOAD_IC) {
__ cmp(ecx, Immediate(isolate()->factory()->prototype_string()));
__ j(not_equal, &miss);
}
StubCompiler::GenerateLoadFunctionPrototype(masm, edx, eax, ebx, &miss);
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, eax,
ebx, &miss);
__ bind(&miss);
StubCompiler::TailCallBuiltin(
masm, BaseLoadStoreStubCompiler::MissBuiltin(kind()));
PropertyAccessCompiler::TailCallBuiltin(
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
}
......
This diff is collapsed.
......@@ -877,7 +877,7 @@ Handle<Code> IC::ComputeHandler(LookupResult* lookup,
Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder(
*receiver_type(), receiver_is_holder, isolate(), &flag);
Handle<Code> code = isolate()->stub_cache()->FindHandler(
Handle<Code> code = PropertyHandlerCompiler::Find(
name, stub_holder_map, handler_kind(), flag,
lookup->holder()->HasFastProperties() ? Code::FAST : Code::NORMAL);
// Use the cached value if it exists, and if it is different from the
......@@ -934,15 +934,15 @@ Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, Handle<Object> object,
Handle<JSFunction>::cast(object)->should_have_prototype() &&
!Handle<JSFunction>::cast(object)->map()->has_non_instance_prototype()) {
Handle<Code> stub;
FunctionPrototypeStub function_prototype_stub(isolate(), kind());
FunctionPrototypeStub function_prototype_stub(isolate());
return function_prototype_stub.GetCode();
}
Handle<HeapType> type = receiver_type();
Handle<JSObject> holder(lookup->holder());
bool receiver_is_holder = object.is_identical_to(holder);
LoadStubCompiler compiler(isolate(), handler_kind(), kNoExtraICState,
cache_holder);
NamedLoadHandlerCompiler compiler(isolate(), handler_kind(), kNoExtraICState,
cache_holder);
switch (lookup->type()) {
case FIELD: {
......@@ -1392,8 +1392,8 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
Handle<JSObject> holder(lookup->holder());
// Handlers do not use strict mode.
StoreStubCompiler compiler(isolate(), SLOPPY, kind());
NamedStoreHandlerCompiler compiler(isolate(), kind());
if (lookup->IsTransition()) {
// Explicitly pass in the receiver map since LookupForWrite may have
// stored something else than the receiver in the holder.
......@@ -1746,43 +1746,43 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
value,
JSReceiver::MAY_BE_STORE_FROM_KEYED),
Object);
} else {
bool use_ic = FLAG_use_ic &&
!object->IsStringWrapper() &&
!object->IsAccessCheckNeeded() &&
!object->IsJSGlobalProxy() &&
!(object->IsJSObject() &&
JSObject::cast(*object)->map()->is_observed());
if (use_ic && !object->IsSmi()) {
// Don't use ICs for maps of the objects in Array's prototype chain. We
// expect to be able to trap element sets to objects with those maps in
// the runtime to enable optimization of element hole access.
Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
if (heap_object->map()->IsMapInArrayPrototypeChain()) use_ic = false;
}
TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
set_target(*stub);
return store_handle;
}
if (use_ic) {
ASSERT(!object->IsAccessCheckNeeded());
bool use_ic =
FLAG_use_ic && !object->IsStringWrapper() &&
!object->IsAccessCheckNeeded() && !object->IsJSGlobalProxy() &&
!(object->IsJSObject() && JSObject::cast(*object)->map()->is_observed());
if (use_ic && !object->IsSmi()) {
// Don't use ICs for maps of the objects in Array's prototype chain. We
// expect to be able to trap element sets to objects with those maps in
// the runtime to enable optimization of element hole access.
Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
if (heap_object->map()->IsMapInArrayPrototypeChain()) use_ic = false;
}
if (object->IsJSObject()) {
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null();
if (receiver->elements()->map() ==
isolate()->heap()->sloppy_arguments_elements_map()) {
if (strict_mode() == SLOPPY) {
stub = sloppy_arguments_stub();
}
} else if (key_is_smi_like &&
!(target().is_identical_to(sloppy_arguments_stub()))) {
// We should go generic if receiver isn't a dictionary, but our
// prototype chain does have dictionary elements. This ensures that
// other non-dictionary receivers in the polymorphic case benefit
// from fast path keyed stores.
if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) {
KeyedAccessStoreMode store_mode =
GetStoreMode(receiver, key, value);
stub = StoreElementStub(receiver, store_mode);
}
if (use_ic) {
ASSERT(!object->IsAccessCheckNeeded());
if (object->IsJSObject()) {
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null();
if (receiver->elements()->map() ==
isolate()->heap()->sloppy_arguments_elements_map()) {
if (strict_mode() == SLOPPY) {
stub = sloppy_arguments_stub();
}
} else if (key_is_smi_like &&
!(target().is_identical_to(sloppy_arguments_stub()))) {
// We should go generic if receiver isn't a dictionary, but our
// prototype chain does have dictionary elements. This ensures that
// other non-dictionary receivers in the polymorphic case benefit
// from fast path keyed stores.
if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) {
KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value);
stub = StoreElementStub(receiver, store_mode);
}
}
}
......@@ -1797,15 +1797,14 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
Object);
}
if (!is_target_set()) {
Code* generic = *generic_stub();
if (*stub == generic) {
TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
}
ASSERT(!stub.is_null());
set_target(*stub);
TRACE_IC("StoreIC", key);
ASSERT(!is_target_set());
Code* generic = *generic_stub();
if (*stub == generic) {
TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
}
ASSERT(!stub.is_null());
set_target(*stub);
TRACE_IC("StoreIC", key);
return store_handle;
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -764,20 +764,12 @@ void MathPowStub::Generate(MacroAssembler* masm) {
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Label miss;
Register receiver = LoadIC::ReceiverRegister();
Register name = LoadIC::NameRegister();
ASSERT(kind() == Code::LOAD_IC ||
kind() == Code::KEYED_LOAD_IC);
if (kind() == Code::KEYED_LOAD_IC) {
__ Cmp(name, isolate()->factory()->prototype_string());
__ j(not_equal, &miss);
}
StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8, r9, &miss);
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8,
r9, &miss);
__ bind(&miss);
StubCompiler::TailCallBuiltin(
masm, BaseLoadStoreStubCompiler::MissBuiltin(kind()));
PropertyAccessCompiler::TailCallBuiltin(
masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
}
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment