Commit 0d89d9a0 authored by verwaest@chromium.org's avatar verwaest@chromium.org

Merge KeyedLoad and NamedLoad stub compiler code.

Review URL: https://chromiumcodereview.appspot.com/12094082

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13579 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent df2a62fb
......@@ -2895,9 +2895,9 @@ Handle<Code> StoreStubCompiler::CompileStoreGlobal(
Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
Handle<String> name,
Handle<JSObject> object,
Handle<JSObject> last,
Handle<String> name,
Handle<GlobalObject> global) {
// ----------- S t a t e -------------
// -- r0 : receiver
......@@ -2941,44 +2941,25 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
}
Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
Handle<JSObject> holder,
PropertyIndex index,
Handle<String> name) {
// ----------- S t a t e -------------
// -- r0 : receiver
// -- r2 : name
// -- lr : return address
// -----------------------------------
Label miss;
Register* LoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { r0, r2, r3, r1, r4, r5 };
return registers;
}
GenerateLoadField(object, holder, r0, r3, r1, r4, index, name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(Code::FIELD, name);
Register* KeyedLoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { r1, r0, r2, r3, r4, r5 };
return registers;
}
Handle<Code> LoadStubCompiler::CompileLoadCallback(
Handle<String> name,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- r0 : receiver
// -- r2 : name
// -- lr : return address
// -----------------------------------
Label miss;
GenerateLoadCallback(object, holder, r0, r2, r3, r1, r4, r5, callback, name,
&miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(Code::CALLBACKS, name);
void KeyedLoadStubCompiler::GenerateNameCheck(Handle<String> name,
Register name_reg,
Label* miss) {
__ cmp(name_reg, Operand(name));
__ b(ne, miss);
}
......@@ -3020,9 +3001,9 @@ void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<String> name,
Handle<JSFunction> getter) {
// ----------- S t a t e -------------
// -- r0 : receiver
......@@ -3045,48 +3026,6 @@ Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
}
Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> value,
Handle<String> name) {
// ----------- S t a t e -------------
// -- r0 : receiver
// -- r2 : name
// -- lr : return address
// -----------------------------------
Label miss;
GenerateLoadConstant(object, holder, r0, r3, r1, r4, value, name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(Code::CONSTANT_FUNCTION, name);
}
Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<String> name) {
// ----------- S t a t e -------------
// -- r0 : receiver
// -- r2 : name
// -- lr : return address
// -----------------------------------
Label miss;
LookupResult lookup(isolate());
LookupPostInterceptor(holder, name, &lookup);
GenerateLoadInterceptor(object, holder, &lookup, r0, r2, r3, r1, r4, name,
&miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(Code::INTERCEPTOR, name);
}
Handle<Code> LoadStubCompiler::CompileLoadGlobal(
Handle<JSObject> object,
Handle<GlobalObject> holder,
......@@ -3129,105 +3068,6 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
PropertyIndex index) {
// ----------- S t a t e -------------
// -- lr : return address
// -- r0 : key
// -- r1 : receiver
// -----------------------------------
Label miss;
// Check the key is the cached one.
__ cmp(r0, Operand(name));
__ b(ne, &miss);
GenerateLoadField(receiver, holder, r1, r2, r3, r4, index, name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
return GetCode(Code::FIELD, name);
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- lr : return address
// -- r0 : key
// -- r1 : receiver
// -----------------------------------
Label miss;
// Check the key is the cached one.
__ cmp(r0, Operand(name));
__ b(ne, &miss);
GenerateLoadCallback(receiver, holder, r1, r0, r2, r3, r4, r5, callback, name,
&miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
return GetCode(Code::CALLBACKS, name);
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<JSFunction> value) {
// ----------- S t a t e -------------
// -- lr : return address
// -- r0 : key
// -- r1 : receiver
// -----------------------------------
Label miss;
// Check the key is the cached one.
__ cmp(r0, Operand(name));
__ b(ne, &miss);
GenerateLoadConstant(receiver, holder, r1, r2, r3, r4, value, name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
return GetCode(Code::CONSTANT_FUNCTION, name);
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<String> name) {
// ----------- S t a t e -------------
// -- lr : return address
// -- r0 : key
// -- r1 : receiver
// -----------------------------------
Label miss;
// Check the key is the cached one.
__ cmp(r0, Operand(name));
__ b(ne, &miss);
LookupResult lookup(isolate());
LookupPostInterceptor(holder, name, &lookup);
GenerateLoadInterceptor(receiver, holder, &lookup, r1, r0, r2, r3, r4, name,
&miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
return GetCode(Code::INTERCEPTOR, name);
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
Handle<Map> receiver_map) {
// ----------- S t a t e -------------
......
......@@ -2965,9 +2965,9 @@ Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
Handle<String> name,
Handle<JSObject> object,
Handle<JSObject> last,
Handle<String> name,
Handle<GlobalObject> global) {
// ----------- S t a t e -------------
// -- ecx : name
......@@ -3013,45 +3013,25 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
}
Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
Handle<JSObject> holder,
PropertyIndex index,
Handle<String> name) {
// ----------- S t a t e -------------
// -- ecx : name
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
Label miss;
GenerateLoadField(object, holder, edx, ebx, eax, edi, index, name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(Code::FIELD, name);
Register* LoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { edx, ecx, ebx, eax, edi, no_reg };
return registers;
}
Handle<Code> LoadStubCompiler::CompileLoadCallback(
Handle<String> name,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- ecx : name
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
Label miss;
Register* KeyedLoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { edx, ecx, ebx, eax, edi, no_reg };
return registers;
}
GenerateLoadCallback(object, holder, edx, ecx, ebx, eax, edi, no_reg,
callback, name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(Code::CALLBACKS, name);
void KeyedLoadStubCompiler::GenerateNameCheck(Handle<String> name,
Register name_reg,
Label* miss) {
__ cmp(name_reg, Immediate(name));
__ j(not_equal, miss);
}
......@@ -3093,9 +3073,9 @@ void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<String> name,
Handle<JSFunction> getter) {
// ----------- S t a t e -------------
// -- ecx : name
......@@ -3118,52 +3098,6 @@ Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
}
Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> value,
Handle<String> name) {
// ----------- S t a t e -------------
// -- ecx : name
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
Label miss;
GenerateLoadConstant(object, holder, edx, ebx, eax, edi, value, name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(Code::CONSTANT_FUNCTION, name);
}
Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<String> name) {
// ----------- S t a t e -------------
// -- ecx : name
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
Label miss;
LookupResult lookup(isolate());
LookupPostInterceptor(holder, name, &lookup);
// TODO(368): Compile in the whole chain: all the interceptors in
// prototypes and ultimate answer.
GenerateLoadInterceptor(receiver, holder, &lookup, edx, ecx, eax, ebx, edi,
name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(Code::INTERCEPTOR, name);
}
Handle<Code> LoadStubCompiler::CompileLoadGlobal(
Handle<JSObject> object,
Handle<GlobalObject> holder,
......@@ -3212,127 +3146,6 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
PropertyIndex index) {
// ----------- S t a t e -------------
// -- ecx : key
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
Label miss;
Counters* counters = isolate()->counters();
__ IncrementCounter(counters->keyed_load_field(), 1);
// Check that the name has not changed.
__ cmp(ecx, Immediate(name));
__ j(not_equal, &miss);
GenerateLoadField(receiver, holder, edx, ebx, eax, edi, index, name, &miss);
__ bind(&miss);
__ DecrementCounter(counters->keyed_load_field(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
return GetCode(Code::FIELD, name);
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- ecx : key
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
Label miss;
Counters* counters = isolate()->counters();
__ IncrementCounter(counters->keyed_load_callback(), 1);
// Check that the name has not changed.
__ cmp(ecx, Immediate(name));
__ j(not_equal, &miss);
GenerateLoadCallback(receiver, holder, edx, ecx, ebx, eax, edi, no_reg,
callback, name, &miss);
__ bind(&miss);
__ DecrementCounter(counters->keyed_load_callback(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
return GetCode(Code::CALLBACKS, name);
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<JSFunction> value) {
// ----------- S t a t e -------------
// -- ecx : key
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
Label miss;
Counters* counters = isolate()->counters();
__ IncrementCounter(counters->keyed_load_constant_function(), 1);
// Check that the name has not changed.
__ cmp(ecx, Immediate(name));
__ j(not_equal, &miss);
GenerateLoadConstant(
receiver, holder, edx, ebx, eax, edi, value, name, &miss);
__ bind(&miss);
__ DecrementCounter(counters->keyed_load_constant_function(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
return GetCode(Code::CONSTANT_FUNCTION, name);
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<String> name) {
// ----------- S t a t e -------------
// -- ecx : key
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
Label miss;
Counters* counters = isolate()->counters();
__ IncrementCounter(counters->keyed_load_interceptor(), 1);
// Check that the name has not changed.
__ cmp(ecx, Immediate(name));
__ j(not_equal, &miss);
LookupResult lookup(isolate());
LookupPostInterceptor(holder, name, &lookup);
GenerateLoadInterceptor(receiver, holder, &lookup, edx, ecx, eax, ebx, edi,
name, &miss);
__ bind(&miss);
__ DecrementCounter(counters->keyed_load_interceptor(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
return GetCode(Code::INTERCEPTOR, name);
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
Handle<Map> receiver_map) {
// ----------- S t a t e -------------
......
......@@ -133,7 +133,7 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name,
LoadStubCompiler compiler(isolate_);
Handle<Code> code =
compiler.CompileLoadNonexistent(cache_name, receiver, current, global);
compiler.CompileLoadNonexistent(receiver, current, cache_name, global);
PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name));
GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code));
JSObject::UpdateMapCodeCache(receiver, cache_name, code);
......@@ -144,7 +144,7 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name,
Handle<Code> StubCache::ComputeLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
PropertyIndex field_index) {
PropertyIndex field) {
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
......@@ -154,8 +154,7 @@ Handle<Code> StubCache::ComputeLoadField(Handle<String> name,
if (probe->IsCode()) return Handle<Code>::cast(probe);
LoadStubCompiler compiler(isolate_);
Handle<Code> code =
compiler.CompileLoadField(receiver, holder, field_index, name);
Handle<Code> code = compiler.CompileLoadField(receiver, holder, name, field);
PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
JSObject::UpdateMapCodeCache(map_holder, name, code);
......@@ -179,7 +178,7 @@ Handle<Code> StubCache::ComputeLoadCallback(Handle<String> name,
LoadStubCompiler compiler(isolate_);
Handle<Code> code =
compiler.CompileLoadCallback(name, receiver, holder, callback);
compiler.CompileLoadCallback(receiver, holder, name, callback);
PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
JSObject::UpdateMapCodeCache(map_holder, name, code);
......@@ -202,7 +201,7 @@ Handle<Code> StubCache::ComputeLoadViaGetter(Handle<String> name,
LoadStubCompiler compiler(isolate_);
Handle<Code> code =
compiler.CompileLoadViaGetter(name, receiver, holder, getter);
compiler.CompileLoadViaGetter(receiver, holder, name, getter);
PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
JSObject::UpdateMapCodeCache(map_holder, name, code);
......@@ -225,7 +224,7 @@ Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name,
LoadStubCompiler compiler(isolate_);
Handle<Code> code =
compiler.CompileLoadConstant(receiver, holder, value, name);
compiler.CompileLoadConstant(receiver, holder, name, value);
PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
JSObject::UpdateMapCodeCache(map_holder, name, code);
......@@ -287,7 +286,7 @@ Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name,
Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
PropertyIndex field_index) {
PropertyIndex field) {
InlineCacheHolderFlag cache_holder =
IC::GetCodeCacheForObject(*receiver, *holder);
Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
......@@ -298,8 +297,7 @@ Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name,
if (probe->IsCode()) return Handle<Code>::cast(probe);
KeyedLoadStubCompiler compiler(isolate_);
Handle<Code> code =
compiler.CompileLoadField(name, receiver, holder, field_index);
Handle<Code> code = compiler.CompileLoadField(receiver, holder, name, field);
PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
JSObject::UpdateMapCodeCache(map_holder, name, code);
......@@ -322,7 +320,7 @@ Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name,
KeyedLoadStubCompiler compiler(isolate_);
Handle<Code> code =
compiler.CompileLoadConstant(name, receiver, holder, value);
compiler.CompileLoadConstant(receiver, holder, name, value);
PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
JSObject::UpdateMapCodeCache(map_holder, name, code);
......@@ -367,7 +365,7 @@ Handle<Code> StubCache::ComputeKeyedLoadCallback(
KeyedLoadStubCompiler compiler(isolate_);
Handle<Code> code =
compiler.CompileLoadCallback(name, receiver, holder, callback);
compiler.CompileLoadCallback(receiver, holder, name, callback);
PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
JSObject::UpdateMapCodeCache(map_holder, name, code);
......@@ -1384,8 +1382,95 @@ void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder,
}
#define __ ACCESS_MASM(masm())
Handle<Code> BaseLoadStubCompiler::CompileLoadField(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<String> name,
PropertyIndex index) {
Label miss;
GenerateNameCheck(name, this->name(), &miss);
GenerateLoadField(object, holder, receiver(),
scratch1(), scratch2(), scratch3(),
index, name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), kind());
// Return the generated code.
return GetCode(Code::FIELD, name);
}
Handle<Code> BaseLoadStubCompiler::CompileLoadCallback(
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<String> name,
Handle<AccessorInfo> callback) {
Label miss;
GenerateNameCheck(name, this->name(), &miss);
GenerateLoadCallback(object, holder, receiver(), this->name(),
scratch1(), scratch2(), scratch3(), scratch4(),
callback, name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), kind());
// Return the generated code.
return GetCode(Code::CALLBACKS, name);
}
Handle<Code> BaseLoadStubCompiler::CompileLoadConstant(
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<String> name,
Handle<JSFunction> value) {
Label miss;
GenerateNameCheck(name, this->name(), &miss);
GenerateLoadConstant(object, holder, receiver(),
scratch1(), scratch2(), scratch3(),
value, name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), kind());
// Return the generated code.
return GetCode(Code::CONSTANT_FUNCTION, name);
}
Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor(
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<String> name) {
Label miss;
LookupResult lookup(isolate());
LookupPostInterceptor(holder, name, &lookup);
GenerateNameCheck(name, this->name(), &miss);
// TODO(368): Compile in the whole chain: all the interceptors in
// prototypes and ultimate answer.
GenerateLoadInterceptor(object, holder, &lookup, receiver(), this->name(),
scratch1(), scratch2(), scratch3(),
name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), kind());
// Return the generated code.
return GetCode(Code::INTERCEPTOR, name);
}
#undef __
Handle<Code> LoadStubCompiler::GetCode(Code::StubType type,
Handle<String> name) {
Handle<String> name,
InlineCacheState state) {
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type);
Handle<Code> code = GetCodeWithFlags(flags, name);
PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
......
......@@ -78,36 +78,36 @@ class StubCache {
// Computes the right stub matching. Inserts the result in the
// cache before returning. This might compile a stub if needed.
Handle<Code> ComputeLoadNonexistent(Handle<String> name,
Handle<JSObject> receiver);
Handle<JSObject> object);
Handle<Code> ComputeLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<JSObject> holder,
PropertyIndex field_index);
Handle<Code> ComputeLoadCallback(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<AccessorInfo> callback);
Handle<Code> ComputeLoadViaGetter(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> getter);
Handle<Code> ComputeLoadConstant(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> value);
Handle<Code> ComputeLoadInterceptor(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<JSObject> holder);
Handle<Code> ComputeLoadNormal();
Handle<Code> ComputeLoadGlobal(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<GlobalObject> holder,
Handle<JSGlobalPropertyCell> cell,
bool is_dont_delete);
......@@ -115,28 +115,28 @@ class StubCache {
// ---
Handle<Code> ComputeKeyedLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<JSObject> holder,
PropertyIndex field_index);
Handle<Code> ComputeKeyedLoadCallback(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<AccessorInfo> callback);
Handle<Code> ComputeKeyedLoadConstant(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> value);
Handle<Code> ComputeKeyedLoadInterceptor(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<JSObject> holder);
// ---
Handle<Code> ComputeStoreField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
int field_index,
Handle<Map> transition,
StrictModeFlag strict_mode);
......@@ -144,30 +144,30 @@ class StubCache {
Handle<Code> ComputeStoreNormal(StrictModeFlag strict_mode);
Handle<Code> ComputeStoreGlobal(Handle<String> name,
Handle<GlobalObject> receiver,
Handle<GlobalObject> object,
Handle<JSGlobalPropertyCell> cell,
StrictModeFlag strict_mode);
Handle<Code> ComputeStoreCallback(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<AccessorInfo> callback,
StrictModeFlag strict_mode);
Handle<Code> ComputeStoreViaSetter(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> setter,
StrictModeFlag strict_mode);
Handle<Code> ComputeStoreInterceptor(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
StrictModeFlag strict_mode);
// ---
Handle<Code> ComputeKeyedStoreField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
int field_index,
Handle<Map> transition,
StrictModeFlag strict_mode);
......@@ -208,7 +208,7 @@ class StubCache {
Code::Kind,
Code::ExtraICState extra_state,
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<GlobalObject> holder,
Handle<JSGlobalPropertyCell> cell,
Handle<JSFunction> function);
......@@ -602,42 +602,69 @@ class StubCompiler BASE_EMBEDDED {
};
class LoadStubCompiler: public StubCompiler {
class BaseLoadStubCompiler: public StubCompiler {
public:
explicit LoadStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
Handle<Code> CompileLoadNonexistent(Handle<String> name,
Handle<JSObject> object,
Handle<JSObject> last,
Handle<GlobalObject> global);
BaseLoadStubCompiler(Isolate* isolate, Register* registers)
: StubCompiler(isolate), registers_(registers) { }
virtual ~BaseLoadStubCompiler() { }
Handle<Code> CompileLoadField(Handle<JSObject> object,
Handle<JSObject> holder,
PropertyIndex index,
Handle<String> name);
Handle<String> name,
PropertyIndex index);
Handle<Code> CompileLoadCallback(Handle<String> name,
Handle<JSObject> object,
Handle<Code> CompileLoadCallback(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<String> name,
Handle<AccessorInfo> callback);
static void GenerateLoadViaGetter(MacroAssembler* masm,
Handle<JSFunction> getter);
Handle<Code> CompileLoadViaGetter(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<JSFunction> getter);
Handle<Code> CompileLoadConstant(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> value,
Handle<String> name);
Handle<String> name,
Handle<JSFunction> value);
Handle<Code> CompileLoadInterceptor(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<String> name);
protected:
Register receiver() { return registers_[0]; }
Register name() { return registers_[1]; }
Register scratch1() { return registers_[2]; }
Register scratch2() { return registers_[3]; }
Register scratch3() { return registers_[4]; }
Register scratch4() { return registers_[5]; }
private:
virtual Code::Kind kind() = 0;
virtual void GenerateNameCheck(Handle<String> name,
Register name_reg,
Label* miss) { }
virtual Handle<Code> GetCode(Code::StubType type,
Handle<String> name,
InlineCacheState state = MONOMORPHIC) = 0;
Register* registers_;
};
class LoadStubCompiler: public BaseLoadStubCompiler {
public:
explicit LoadStubCompiler(Isolate* isolate)
: BaseLoadStubCompiler(isolate, registers()) { }
Handle<Code> CompileLoadNonexistent(Handle<JSObject> object,
Handle<JSObject> last,
Handle<String> name,
Handle<GlobalObject> global);
static void GenerateLoadViaGetter(MacroAssembler* masm,
Handle<JSFunction> getter);
Handle<Code> CompileLoadViaGetter(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<String> name,
Handle<JSFunction> getter);
Handle<Code> CompileLoadGlobal(Handle<JSObject> object,
Handle<GlobalObject> holder,
Handle<JSGlobalPropertyCell> cell,
......@@ -645,32 +672,18 @@ class LoadStubCompiler: public StubCompiler {
bool is_dont_delete);
private:
Handle<Code> GetCode(Code::StubType type, Handle<String> name);
Register* registers();
virtual Code::Kind kind() { return Code::LOAD_IC; }
virtual Handle<Code> GetCode(Code::StubType type,
Handle<String> name,
InlineCacheState state = MONOMORPHIC);
};
class KeyedLoadStubCompiler: public StubCompiler {
class KeyedLoadStubCompiler: public BaseLoadStubCompiler {
public:
explicit KeyedLoadStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
Handle<Code> CompileLoadField(Handle<String> name,
Handle<JSObject> object,
Handle<JSObject> holder,
PropertyIndex index);
Handle<Code> CompileLoadCallback(Handle<String> name,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<AccessorInfo> callback);
Handle<Code> CompileLoadConstant(Handle<String> name,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> value);
Handle<Code> CompileLoadInterceptor(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<String> name);
explicit KeyedLoadStubCompiler(Isolate* isolate)
: BaseLoadStubCompiler(isolate, registers()) { }
Handle<Code> CompileLoadElement(Handle<Map> receiver_map);
......@@ -682,9 +695,14 @@ class KeyedLoadStubCompiler: public StubCompiler {
static void GenerateLoadDictionaryElement(MacroAssembler* masm);
private:
Handle<Code> GetCode(Code::StubType type,
Handle<String> name,
InlineCacheState state = MONOMORPHIC);
Register* registers();
virtual Code::Kind kind() { return Code::KEYED_LOAD_IC; }
virtual Handle<Code> GetCode(Code::StubType type,
Handle<String> name,
InlineCacheState state = MONOMORPHIC);
virtual void GenerateNameCheck(Handle<String> name,
Register name_reg,
Label* miss);
};
......@@ -700,7 +718,7 @@ class StoreStubCompiler: public StubCompiler {
Handle<String> name);
Handle<Code> CompileStoreCallback(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<AccessorInfo> callback);
......@@ -708,7 +726,7 @@ class StoreStubCompiler: public StubCompiler {
Handle<JSFunction> setter);
Handle<Code> CompileStoreViaSetter(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> setter);
......
......@@ -2790,9 +2790,9 @@ Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
Handle<String> name,
Handle<JSObject> object,
Handle<JSObject> last,
Handle<String> name,
Handle<GlobalObject> global) {
// ----------- S t a t e -------------
// -- rax : receiver
......@@ -2837,44 +2837,25 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
}
Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
Handle<JSObject> holder,
PropertyIndex index,
Handle<String> name) {
// ----------- S t a t e -------------
// -- rax : receiver
// -- rcx : name
// -- rsp[0] : return address
// -----------------------------------
Label miss;
Register* LoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { rax, rcx, rbx, rdx, rdi, r8 };
return registers;
}
GenerateLoadField(object, holder, rax, rbx, rdx, rdi, index, name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(Code::FIELD, name);
Register* KeyedLoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { rdx, rax, rbx, rcx, rdi, r8 };
return registers;
}
Handle<Code> LoadStubCompiler::CompileLoadCallback(
Handle<String> name,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- rax : receiver
// -- rcx : name
// -- rsp[0] : return address
// -----------------------------------
Label miss;
GenerateLoadCallback(object, holder, rax, rcx, rdx, rbx, rdi, r8, callback,
name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(Code::CALLBACKS, name);
void KeyedLoadStubCompiler::GenerateNameCheck(Handle<String> name,
Register name_reg,
Label* miss) {
__ Cmp(name_reg, name);
__ j(not_equal, miss);
}
......@@ -2916,9 +2897,9 @@ void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<String> name,
Handle<JSFunction> getter) {
// ----------- S t a t e -------------
// -- rax : receiver
......@@ -2941,50 +2922,6 @@ Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
}
Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
Handle<JSObject> holder,
Handle<JSFunction> value,
Handle<String> name) {
// ----------- S t a t e -------------
// -- rax : receiver
// -- rcx : name
// -- rsp[0] : return address
// -----------------------------------
Label miss;
GenerateLoadConstant(object, holder, rax, rbx, rdx, rdi, value, name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(Code::CONSTANT_FUNCTION, name);
}
Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<String> name) {
// ----------- S t a t e -------------
// -- rax : receiver
// -- rcx : name
// -- rsp[0] : return address
// -----------------------------------
Label miss;
LookupResult lookup(isolate());
LookupPostInterceptor(holder, name, &lookup);
// TODO(368): Compile in the whole chain: all the interceptors in
// prototypes and ultimate answer.
GenerateLoadInterceptor(receiver, holder, &lookup, rax, rcx, rdx, rbx, rdi,
name, &miss);
__ bind(&miss);
GenerateLoadMiss(masm(), Code::LOAD_IC);
// Return the generated code.
return GetCode(Code::INTERCEPTOR, name);
}
Handle<Code> LoadStubCompiler::CompileLoadGlobal(
Handle<JSObject> object,
Handle<GlobalObject> holder,
......@@ -3029,124 +2966,6 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal(
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
PropertyIndex index) {
// ----------- S t a t e -------------
// -- rax : key
// -- rdx : receiver
// -- rsp[0] : return address
// -----------------------------------
Label miss;
Counters* counters = isolate()->counters();
__ IncrementCounter(counters->keyed_load_field(), 1);
// Check that the name has not changed.
__ Cmp(rax, name);
__ j(not_equal, &miss);
GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss);
__ bind(&miss);
__ DecrementCounter(counters->keyed_load_field(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
return GetCode(Code::FIELD, name);
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<AccessorInfo> callback) {
// ----------- S t a t e -------------
// -- rax : key
// -- rdx : receiver
// -- rsp[0] : return address
// -----------------------------------
Label miss;
Counters* counters = isolate()->counters();
__ IncrementCounter(counters->keyed_load_callback(), 1);
// Check that the name has not changed.
__ Cmp(rax, name);
__ j(not_equal, &miss);
GenerateLoadCallback(receiver, holder, rdx, rax, rbx, rcx, rdi, r8, callback,
name, &miss);
__ bind(&miss);
__ DecrementCounter(counters->keyed_load_callback(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
return GetCode(Code::CALLBACKS, name);
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
Handle<String> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<JSFunction> value) {
// ----------- S t a t e -------------
// -- rax : key
// -- rdx : receiver
// -- rsp[0] : return address
// -----------------------------------
Label miss;
Counters* counters = isolate()->counters();
__ IncrementCounter(counters->keyed_load_constant_function(), 1);
// Check that the name has not changed.
__ Cmp(rax, name);
__ j(not_equal, &miss);
GenerateLoadConstant(receiver, holder, rdx, rbx, rcx, rdi,
value, name, &miss);
__ bind(&miss);
__ DecrementCounter(counters->keyed_load_constant_function(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
return GetCode(Code::CONSTANT_FUNCTION, name);
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<String> name) {
// ----------- S t a t e -------------
// -- rax : key
// -- rdx : receiver
// -- rsp[0] : return address
// -----------------------------------
Label miss;
Counters* counters = isolate()->counters();
__ IncrementCounter(counters->keyed_load_interceptor(), 1);
// Check that the name has not changed.
__ Cmp(rax, name);
__ j(not_equal, &miss);
LookupResult lookup(isolate());
LookupPostInterceptor(holder, name, &lookup);
GenerateLoadInterceptor(receiver, holder, &lookup, rdx, rax, rcx, rbx, rdi,
name, &miss);
__ bind(&miss);
__ DecrementCounter(counters->keyed_load_interceptor(), 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
// Return the generated code.
return GetCode(Code::INTERCEPTOR, name);
}
Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
Handle<Map> receiver_map) {
// ----------- S t a t e -------------
......
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