Index: src/stub-cache.cc |
=================================================================== |
--- src/stub-cache.cc (revision 5007) |
+++ src/stub-cache.cc (working copy) |
@@ -94,6 +94,7 @@ |
Object* StubCache::ComputeLoadNonexistent(String* name, JSObject* receiver) { |
+ ASSERT(receiver->IsGlobalObject() || receiver->HasFastProperties()); |
// If no global objects are present in the prototype chain, the load |
// nonexistent IC stub can be shared for all names for a given map |
// and we use the empty string for the map cache in that case. If |
@@ -129,14 +130,16 @@ |
JSObject* receiver, |
JSObject* holder, |
int field_index) { |
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
+ Map* map = receiver->map(); |
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD); |
- Object* code = receiver->map()->FindInCodeCache(name, flags); |
+ Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
LoadStubCompiler compiler; |
code = compiler.CompileLoadField(receiver, holder, field_index, name); |
if (code->IsFailure()) return code; |
PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); |
- Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
+ Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
return code; |
@@ -148,14 +151,16 @@ |
JSObject* holder, |
AccessorInfo* callback) { |
ASSERT(v8::ToCData<Address>(callback->getter()) != 0); |
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
+ Map* map = receiver->map(); |
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS); |
- Object* code = receiver->map()->FindInCodeCache(name, flags); |
+ Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
LoadStubCompiler compiler; |
code = compiler.CompileLoadCallback(name, receiver, holder, callback); |
if (code->IsFailure()) return code; |
PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); |
- Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
+ Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
return code; |
@@ -166,15 +171,17 @@ |
JSObject* receiver, |
JSObject* holder, |
Object* value) { |
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
+ Map* map = receiver->map(); |
Code::Flags flags = |
Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION); |
- Object* code = receiver->map()->FindInCodeCache(name, flags); |
+ Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
LoadStubCompiler compiler; |
code = compiler.CompileLoadConstant(receiver, holder, value, name); |
if (code->IsFailure()) return code; |
PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); |
- Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
+ Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
return code; |
@@ -184,14 +191,16 @@ |
Object* StubCache::ComputeLoadInterceptor(String* name, |
JSObject* receiver, |
JSObject* holder) { |
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
+ Map* map = receiver->map(); |
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR); |
- Object* code = receiver->map()->FindInCodeCache(name, flags); |
+ Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
LoadStubCompiler compiler; |
code = compiler.CompileLoadInterceptor(receiver, holder, name); |
if (code->IsFailure()) return code; |
PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); |
- Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
+ Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
return code; |
@@ -208,8 +217,10 @@ |
GlobalObject* holder, |
JSGlobalPropertyCell* cell, |
bool is_dont_delete) { |
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
+ Map* map = receiver->map(); |
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); |
- Object* code = receiver->map()->FindInCodeCache(name, flags); |
+ Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
LoadStubCompiler compiler; |
code = compiler.CompileLoadGlobal(receiver, |
@@ -219,7 +230,7 @@ |
is_dont_delete); |
if (code->IsFailure()) return code; |
PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); |
- Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
+ Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
return code; |
@@ -230,14 +241,16 @@ |
JSObject* receiver, |
JSObject* holder, |
int field_index) { |
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
+ Map* map = receiver->map(); |
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD); |
- Object* code = receiver->map()->FindInCodeCache(name, flags); |
+ Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
KeyedLoadStubCompiler compiler; |
code = compiler.CompileLoadField(name, receiver, holder, field_index); |
if (code->IsFailure()) return code; |
PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
- Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
+ Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
return code; |
@@ -248,15 +261,17 @@ |
JSObject* receiver, |
JSObject* holder, |
Object* value) { |
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
+ Map* map = receiver->map(); |
Code::Flags flags = |
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION); |
- Object* code = receiver->map()->FindInCodeCache(name, flags); |
+ Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
KeyedLoadStubCompiler compiler; |
code = compiler.CompileLoadConstant(name, receiver, holder, value); |
if (code->IsFailure()) return code; |
PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
- Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
+ Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
return code; |
@@ -266,15 +281,17 @@ |
Object* StubCache::ComputeKeyedLoadInterceptor(String* name, |
JSObject* receiver, |
JSObject* holder) { |
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
+ Map* map = receiver->map(); |
Code::Flags flags = |
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR); |
- Object* code = receiver->map()->FindInCodeCache(name, flags); |
+ Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
KeyedLoadStubCompiler compiler; |
code = compiler.CompileLoadInterceptor(receiver, holder, name); |
if (code->IsFailure()) return code; |
PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
- Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
+ Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
return code; |
@@ -285,15 +302,17 @@ |
JSObject* receiver, |
JSObject* holder, |
AccessorInfo* callback) { |
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); |
+ Map* map = receiver->map(); |
Code::Flags flags = |
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); |
- Object* code = receiver->map()->FindInCodeCache(name, flags); |
+ Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
KeyedLoadStubCompiler compiler; |
code = compiler.CompileLoadCallback(name, receiver, holder, callback); |
if (code->IsFailure()) return code; |
PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
- Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
+ Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
return code; |
@@ -305,13 +324,15 @@ |
JSArray* receiver) { |
Code::Flags flags = |
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); |
- Object* code = receiver->map()->FindInCodeCache(name, flags); |
+ ASSERT(receiver->IsJSObject()); |
+ Map* map = receiver->map(); |
+ Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
KeyedLoadStubCompiler compiler; |
code = compiler.CompileLoadArrayLength(name); |
if (code->IsFailure()) return code; |
PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
- Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
+ Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
return code; |
@@ -322,13 +343,14 @@ |
String* receiver) { |
Code::Flags flags = |
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); |
- Object* code = receiver->map()->FindInCodeCache(name, flags); |
+ Map* map = receiver->map(); |
+ Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
KeyedLoadStubCompiler compiler; |
code = compiler.CompileLoadStringLength(name); |
if (code->IsFailure()) return code; |
PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
- Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
+ Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
return code; |
@@ -339,13 +361,14 @@ |
JSFunction* receiver) { |
Code::Flags flags = |
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); |
- Object* code = receiver->map()->FindInCodeCache(name, flags); |
+ Map* map = receiver->map(); |
+ Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
KeyedLoadStubCompiler compiler; |
code = compiler.CompileLoadFunctionPrototype(name); |
if (code->IsFailure()) return code; |
PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name)); |
- Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
+ Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
return code; |
@@ -385,7 +408,7 @@ |
StoreStubCompiler compiler; |
code = compiler.CompileStoreGlobal(receiver, cell, name); |
if (code->IsFailure()) return code; |
- PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); |
+ PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); |
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
@@ -456,7 +479,9 @@ |
JSObject* holder, |
JSFunction* function) { |
// Compute the check type and the map. |
- Map* map = IC::GetCodeCacheMapForObject(object); |
+ InlineCacheHolderFlag cache_holder = |
+ IC::GetCodeCacheForObject(object, holder); |
+ Map* map = IC::GetCodeCacheMap(object, cache_holder); |
// Compute check type based on receiver/holder. |
StubCompiler::CheckType check = StubCompiler::RECEIVER_MAP_CHECK; |
@@ -471,6 +496,7 @@ |
Code::Flags flags = |
Code::ComputeMonomorphicFlags(kind, |
CONSTANT_FUNCTION, |
+ cache_holder, |
in_loop, |
argc); |
Object* code = map->FindInCodeCache(name, flags); |
@@ -481,7 +507,7 @@ |
// caches. |
if (!function->is_compiled()) return Failure::InternalError(); |
// Compile the stub - only create stubs for fully compiled functions. |
- CallStubCompiler compiler(argc, in_loop, kind); |
+ CallStubCompiler compiler(argc, in_loop, kind, cache_holder); |
code = compiler.CompileCallConstant(object, holder, function, name, check); |
if (code->IsFailure()) return code; |
ASSERT_EQ(flags, Code::cast(code)->flags()); |
@@ -502,7 +528,9 @@ |
JSObject* holder, |
int index) { |
// Compute the check type and the map. |
- Map* map = IC::GetCodeCacheMapForObject(object); |
+ InlineCacheHolderFlag cache_holder = |
+ IC::GetCodeCacheForObject(object, holder); |
+ Map* map = IC::GetCodeCacheMap(object, cache_holder); |
// TODO(1233596): We cannot do receiver map check for non-JS objects |
// because they may be represented as immediates without a |
@@ -513,11 +541,12 @@ |
Code::Flags flags = Code::ComputeMonomorphicFlags(kind, |
FIELD, |
+ cache_holder, |
in_loop, |
argc); |
Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
- CallStubCompiler compiler(argc, in_loop, kind); |
+ CallStubCompiler compiler(argc, in_loop, kind, cache_holder); |
code = compiler.CompileCallField(JSObject::cast(object), |
holder, |
index, |
@@ -539,8 +568,9 @@ |
Object* object, |
JSObject* holder) { |
// Compute the check type and the map. |
- // If the object is a value, we use the prototype map for the cache. |
- Map* map = IC::GetCodeCacheMapForObject(object); |
+ InlineCacheHolderFlag cache_holder = |
+ IC::GetCodeCacheForObject(object, holder); |
+ Map* map = IC::GetCodeCacheMap(object, cache_holder); |
// TODO(1233596): We cannot do receiver map check for non-JS objects |
// because they may be represented as immediates without a |
@@ -552,11 +582,12 @@ |
Code::Flags flags = |
Code::ComputeMonomorphicFlags(kind, |
INTERCEPTOR, |
+ cache_holder, |
NOT_IN_LOOP, |
argc); |
Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
- CallStubCompiler compiler(argc, NOT_IN_LOOP, kind); |
+ CallStubCompiler compiler(argc, NOT_IN_LOOP, kind, cache_holder); |
code = compiler.CompileCallInterceptor(JSObject::cast(object), |
holder, |
name); |
@@ -590,25 +621,29 @@ |
GlobalObject* holder, |
JSGlobalPropertyCell* cell, |
JSFunction* function) { |
+ InlineCacheHolderFlag cache_holder = |
+ IC::GetCodeCacheForObject(receiver, holder); |
+ Map* map = IC::GetCodeCacheMap(receiver, cache_holder); |
Code::Flags flags = |
Code::ComputeMonomorphicFlags(kind, |
NORMAL, |
+ cache_holder, |
in_loop, |
argc); |
- Object* code = receiver->map()->FindInCodeCache(name, flags); |
+ Object* code = map->FindInCodeCache(name, flags); |
if (code->IsUndefined()) { |
// If the function hasn't been compiled yet, we cannot do it now |
// because it may cause GC. To avoid this issue, we return an |
// internal error which will make sure we do not update any |
// caches. |
if (!function->is_compiled()) return Failure::InternalError(); |
- CallStubCompiler compiler(argc, in_loop, kind); |
+ CallStubCompiler compiler(argc, in_loop, kind, cache_holder); |
code = compiler.CompileCallGlobal(receiver, holder, cell, function, name); |
if (code->IsFailure()) return code; |
ASSERT_EQ(flags, Code::cast(code)->flags()); |
PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
Code::cast(code), name)); |
- Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
+ Object* result = map->UpdateCodeCache(name, Code::cast(code)); |
if (result->IsFailure()) return result; |
} |
return code; |
@@ -1208,6 +1243,17 @@ |
} |
+CallStubCompiler::CallStubCompiler(int argc, |
+ InLoopFlag in_loop, |
+ Code::Kind kind, |
+ InlineCacheHolderFlag cache_holder) |
+ : arguments_(argc) |
+ , in_loop_(in_loop) |
+ , kind_(kind) |
+ , cache_holder_(cache_holder) { |
+} |
+ |
+ |
Object* CallStubCompiler::CompileCustomCall(int generator_id, |
Object* object, |
JSObject* holder, |
@@ -1235,6 +1281,7 @@ |
int argc = arguments_.immediate(); |
Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, |
type, |
+ cache_holder_, |
in_loop_, |
argc); |
return GetCodeWithFlags(flags, name); |