Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(207)

Side by Side Diff: src/stub-cache.cc

Issue 80693002: Only use Type for compiling load handlers. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/stub-cache.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 // Update primary cache. 93 // Update primary cache.
94 primary->key = name; 94 primary->key = name;
95 primary->value = code; 95 primary->value = code;
96 primary->map = map; 96 primary->map = map;
97 isolate()->counters()->megamorphic_stub_cache_updates()->Increment(); 97 isolate()->counters()->megamorphic_stub_cache_updates()->Increment();
98 return code; 98 return code;
99 } 99 }
100 100
101 101
102 Handle<Code> StubCache::FindIC(Handle<Name> name, 102 Handle<Code> StubCache::FindIC(Handle<Name> name,
103 Handle<Map> stub_holder_map, 103 Handle<Map> stub_holder,
104 Code::Kind kind, 104 Code::Kind kind,
105 Code::ExtraICState extra_state, 105 Code::ExtraICState extra_state,
106 InlineCacheHolderFlag cache_holder) { 106 InlineCacheHolderFlag cache_holder) {
107 Code::Flags flags = Code::ComputeMonomorphicFlags( 107 Code::Flags flags = Code::ComputeMonomorphicFlags(
108 kind, extra_state, cache_holder); 108 kind, extra_state, cache_holder);
109 Handle<Object> probe(stub_holder_map->FindInCodeCache(*name, flags), 109 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_);
110 isolate_);
111 if (probe->IsCode()) return Handle<Code>::cast(probe); 110 if (probe->IsCode()) return Handle<Code>::cast(probe);
112 return Handle<Code>::null(); 111 return Handle<Code>::null();
113 } 112 }
114 113
115 114
116 Handle<Code> StubCache::FindHandler(Handle<Name> name, 115 Handle<Code> StubCache::FindHandler(Handle<Name> name,
117 Handle<HeapObject> stub_holder, 116 Handle<Map> stub_holder,
118 Code::Kind kind, 117 Code::Kind kind,
119 InlineCacheHolderFlag cache_holder, 118 InlineCacheHolderFlag cache_holder,
120 StrictModeFlag strict_mode) { 119 StrictModeFlag strict_mode) {
121 Code::ExtraICState extra_ic_state = Code::kNoExtraICState; 120 Code::ExtraICState extra_ic_state = Code::kNoExtraICState;
122 if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) { 121 if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) {
123 extra_ic_state = Code::ComputeExtraICState( 122 extra_ic_state = Code::ComputeExtraICState(
124 STANDARD_STORE, strict_mode); 123 STANDARD_STORE, strict_mode);
125 } 124 }
126 Code::Flags flags = Code::ComputeMonomorphicFlags( 125 Code::Flags flags = Code::ComputeMonomorphicFlags(
127 Code::HANDLER, extra_ic_state, cache_holder, Code::NORMAL, kind); 126 Code::HANDLER, extra_ic_state, cache_holder, Code::NORMAL, kind);
128 127
129 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), 128 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_);
130 isolate_);
131 if (probe->IsCode()) return Handle<Code>::cast(probe); 129 if (probe->IsCode()) return Handle<Code>::cast(probe);
132 return Handle<Code>::null(); 130 return Handle<Code>::null();
133 } 131 }
134 132
135 133
136 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name, 134 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name,
137 Handle<Type> type, 135 Handle<Type> type,
138 Handle<Code> handler, 136 Handle<Code> handler,
139 StrictModeFlag strict_mode) { 137 StrictModeFlag strict_mode) {
140 Code::Kind kind = handler->handler_kind(); 138 Code::Kind kind = handler->handler_kind();
(...skipping 25 matching lines...) Expand all
166 KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE); 164 KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE);
167 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); 165 ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
168 } 166 }
169 167
170 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); 168 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic);
171 return ic; 169 return ic;
172 } 170 }
173 171
174 172
175 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, 173 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
176 Handle<Object> object) { 174 Handle<Type> type) {
177 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); 175 InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type);
178 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( 176 Handle<Map> stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate());
179 isolate(), *object, cache_holder)); 177 // If no dictionary mode objects are present in the prototype chain, the load
180 // If no global objects are present in the prototype chain, the load 178 // nonexistent IC stub can be shared for all names for a given map and we use
181 // nonexistent IC stub can be shared for all names for a given map 179 // the empty string for the map cache in that case. If there are dictionary
182 // and we use the empty string for the map cache in that case. If 180 // mode objects involved, we need to do negative lookups in the stub and
183 // there are global objects involved, we need to check global 181 // therefore the stub will be specific to the name.
184 // property cells in the stub and therefore the stub will be 182 Handle<Map> current_map = stub_holder;
185 // specific to the name. 183 Handle<Name> cache_name = current_map->is_dictionary_map()
186 Handle<Name> cache_name = factory()->empty_string(); 184 ? name : Handle<Name>::cast(isolate()->factory()->empty_string());
187 Handle<JSObject> current; 185 Handle<Object> next(current_map->prototype(), isolate());
188 Handle<Object> next = stub_holder; 186 Handle<JSObject> last = Handle<JSObject>::null();
189 Handle<JSGlobalObject> global; 187 while (!next->IsNull()) {
190 do { 188 last = Handle<JSObject>::cast(next);
191 current = Handle<JSObject>::cast(next); 189 next = handle(current_map->prototype(), isolate());
192 next = Handle<Object>(current->GetPrototype(), isolate_); 190 current_map = handle(Handle<HeapObject>::cast(next)->map());
193 if (current->IsJSGlobalObject()) { 191 if (current_map->is_dictionary_map()) cache_name = name;
194 global = Handle<JSGlobalObject>::cast(current); 192 }
195 cache_name = name;
196 } else if (!current->HasFastProperties()) {
197 cache_name = name;
198 }
199 } while (!next->IsNull());
200 193
201 // Compile the stub that is either shared for all names or 194 // Compile the stub that is either shared for all names or
202 // name specific if there are global objects involved. 195 // name specific if there are global objects involved.
203 Handle<Code> handler = FindHandler( 196 Handle<Code> handler = FindHandler(
204 cache_name, stub_holder, Code::LOAD_IC, cache_holder); 197 cache_name, stub_holder, Code::LOAD_IC, flag);
205 if (!handler.is_null()) return handler; 198 if (!handler.is_null()) return handler;
206 199
207 LoadStubCompiler compiler(isolate_, cache_holder); 200 LoadStubCompiler compiler(isolate_, flag);
208 handler = 201 handler = compiler.CompileLoadNonexistent(type, last, cache_name);
209 compiler.CompileLoadNonexistent(object, current, cache_name, global); 202 Map::UpdateCodeCache(stub_holder, cache_name, handler);
210 HeapObject::UpdateMapCodeCache(stub_holder, cache_name, handler);
211 return handler; 203 return handler;
212 } 204 }
213 205
214 206
215 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { 207 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) {
216 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); 208 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
217 Handle<Name> name = 209 Handle<Name> name =
218 isolate()->factory()->KeyedLoadElementMonomorphic_string(); 210 isolate()->factory()->KeyedLoadElementMonomorphic_string();
219 211
220 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); 212 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_);
(...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 if (lookup->IsFound()) return; 1120 if (lookup->IsFound()) return;
1129 if (holder->GetPrototype()->IsNull()) return; 1121 if (holder->GetPrototype()->IsNull()) return;
1130 holder->GetPrototype()->Lookup(*name, lookup); 1122 holder->GetPrototype()->Lookup(*name, lookup);
1131 } 1123 }
1132 1124
1133 1125
1134 #define __ ACCESS_MASM(masm()) 1126 #define __ ACCESS_MASM(masm())
1135 1127
1136 1128
1137 Register LoadStubCompiler::HandlerFrontendHeader( 1129 Register LoadStubCompiler::HandlerFrontendHeader(
1138 Handle<Object> object, 1130 Handle<Type> type,
1139 Register object_reg, 1131 Register object_reg,
1140 Handle<JSObject> holder, 1132 Handle<JSObject> holder,
1141 Handle<Name> name, 1133 Handle<Name> name,
1142 Label* miss) { 1134 Label* miss) {
1143 Handle<JSObject> receiver;
1144 PrototypeCheckType check_type = CHECK_ALL_MAPS; 1135 PrototypeCheckType check_type = CHECK_ALL_MAPS;
1145 int function_index = -1; 1136 int function_index = -1;
1146 if (object->IsJSObject()) { 1137 if (type->Is(Type::String())) {
1147 receiver = Handle<JSObject>::cast(object); 1138 function_index = Context::STRING_FUNCTION_INDEX;
1139 } else if (type->Is(Type::Symbol())) {
1140 function_index = Context::SYMBOL_FUNCTION_INDEX;
1141 } else if (type->Is(Type::Number())) {
1142 function_index = Context::NUMBER_FUNCTION_INDEX;
1143 } else if (type->Is(Type::Boolean())) {
1144 // Booleans use the generic oddball map, so an additional check is needed to
1145 // ensure the receiver is really a boolean.
1146 GenerateBooleanCheck(object_reg, miss);
1147 function_index = Context::BOOLEAN_FUNCTION_INDEX;
1148 } else {
1148 check_type = SKIP_RECEIVER; 1149 check_type = SKIP_RECEIVER;
1149 } else { 1150 }
1150 if (object->IsString()) {
1151 function_index = Context::STRING_FUNCTION_INDEX;
1152 } else if (object->IsSymbol()) {
1153 function_index = Context::SYMBOL_FUNCTION_INDEX;
1154 } else if (object->IsNumber()) {
1155 function_index = Context::NUMBER_FUNCTION_INDEX;
1156 } else {
1157 ASSERT(object->IsBoolean());
1158 // Booleans use the generic oddball map, so an additional check is
1159 // needed to ensure the receiver is really a boolean.
1160 GenerateBooleanCheck(object_reg, miss);
1161 function_index = Context::BOOLEAN_FUNCTION_INDEX;
1162 }
1163 1151
1152 if (check_type == CHECK_ALL_MAPS) {
1164 GenerateDirectLoadGlobalFunctionPrototype( 1153 GenerateDirectLoadGlobalFunctionPrototype(
1165 masm(), function_index, scratch1(), miss); 1154 masm(), function_index, scratch1(), miss);
1166 receiver = handle(JSObject::cast(object->GetPrototype(isolate()))); 1155 Object* function = isolate()->native_context()->get(function_index);
1156 Object* prototype = JSFunction::cast(function)->instance_prototype();
1157 type = IC::CurrentTypeOf(handle(prototype, isolate()), isolate());
1167 object_reg = scratch1(); 1158 object_reg = scratch1();
1168 } 1159 }
1169 1160
1170 // Check that the maps starting from the prototype haven't changed. 1161 // Check that the maps starting from the prototype haven't changed.
1171 return CheckPrototypes( 1162 return CheckPrototypes(
1172 IC::CurrentTypeOf(receiver, isolate()), object_reg, holder, 1163 type, object_reg, holder, scratch1(), scratch2(), scratch3(),
1173 scratch1(), scratch2(), scratch3(), name, miss, check_type); 1164 name, miss, check_type);
1174 } 1165 }
1175 1166
1176 1167
1177 // HandlerFrontend for store uses the name register. It has to be restored 1168 // HandlerFrontend for store uses the name register. It has to be restored
1178 // before a miss. 1169 // before a miss.
1179 Register StoreStubCompiler::HandlerFrontendHeader( 1170 Register StoreStubCompiler::HandlerFrontendHeader(
1180 Handle<Object> object, 1171 Handle<Type> type,
1181 Register object_reg, 1172 Register object_reg,
1182 Handle<JSObject> holder, 1173 Handle<JSObject> holder,
1183 Handle<Name> name, 1174 Handle<Name> name,
1184 Label* miss) { 1175 Label* miss) {
1185 return CheckPrototypes( 1176 return CheckPrototypes(type, object_reg, holder, this->name(),
1186 IC::CurrentTypeOf(object, isolate()), object_reg, holder, this->name(), 1177 scratch1(), scratch2(), name, miss, SKIP_RECEIVER);
1187 scratch1(), scratch2(), name, miss, SKIP_RECEIVER);
1188 } 1178 }
1189 1179
1190 1180
1191 bool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) { 1181 bool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) {
1192 for (int i = 0; i < types->length(); ++i) { 1182 for (int i = 0; i < types->length(); ++i) {
1193 if (types->at(i)->Is(Type::Number())) return true; 1183 if (types->at(i)->Is(Type::Number())) return true;
1194 } 1184 }
1195 return false; 1185 return false;
1196 } 1186 }
1197 1187
1198 1188
1199 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Object> object, 1189 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Type> type,
1200 Register object_reg, 1190 Register object_reg,
1201 Handle<JSObject> holder, 1191 Handle<JSObject> holder,
1202 Handle<Name> name) { 1192 Handle<Name> name) {
1203 Label miss; 1193 Label miss;
1204 1194
1205 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1195 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss);
1206 1196
1207 HandlerFrontendFooter(name, &miss); 1197 HandlerFrontendFooter(name, &miss);
1208 1198
1209 return reg; 1199 return reg;
1210 } 1200 }
1211 1201
1212 1202
1213 void LoadStubCompiler::NonexistentHandlerFrontend( 1203 void LoadStubCompiler::NonexistentHandlerFrontend(Handle<Type> type,
1214 Handle<Object> object, 1204 Handle<JSObject> last,
1215 Handle<JSObject> last, 1205 Handle<Name> name) {
1216 Handle<Name> name,
1217 Handle<JSGlobalObject> global) {
1218 Label miss; 1206 Label miss;
1219 1207
1220 Register holder = HandlerFrontendHeader( 1208 Register holder;
1221 object, receiver(), last, name, &miss); 1209 Handle<Map> last_map;
1210 if (last.is_null()) {
1211 holder = receiver();
1212 last_map = IC::TypeToMap(*type, isolate());
1213 // If |type| has null as its prototype, |last| is Handle<JSObject>::null().
1214 ASSERT(last_map->prototype() == isolate()->heap()->null_value());
1215 } else {
1216 holder = HandlerFrontendHeader(type, receiver(), last, name, &miss);
1217 last_map = handle(last->map());
1218 }
1222 1219
1223 if (!last->HasFastProperties() && 1220 if (last_map->is_dictionary_map() &&
1224 !last->IsJSGlobalObject() && 1221 !last_map->IsJSGlobalObjectMap() &&
1225 !last->IsJSGlobalProxy()) { 1222 !last_map->IsJSGlobalProxyMap()) {
1226 if (!name->IsUniqueName()) { 1223 if (!name->IsUniqueName()) {
1227 ASSERT(name->IsString()); 1224 ASSERT(name->IsString());
1228 name = factory()->InternalizeString(Handle<String>::cast(name)); 1225 name = factory()->InternalizeString(Handle<String>::cast(name));
1229 } 1226 }
1230 ASSERT(last->property_dictionary()->FindEntry(*name) == 1227 ASSERT(last.is_null() ||
1231 NameDictionary::kNotFound); 1228 last->property_dictionary()->FindEntry(*name) ==
1229 NameDictionary::kNotFound);
1232 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name, 1230 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name,
1233 scratch2(), scratch3()); 1231 scratch2(), scratch3());
1234 } 1232 }
1235 1233
1236 // If the last object in the prototype chain is a global object, 1234 // If the last object in the prototype chain is a global object,
1237 // check that the global property cell is empty. 1235 // check that the global property cell is empty.
1238 if (!global.is_null()) { 1236 if (last_map->IsJSGlobalObjectMap()) {
1237 Handle<JSGlobalObject> global = last.is_null()
1238 ? Handle<JSGlobalObject>::cast(type->AsConstant())
1239 : Handle<JSGlobalObject>::cast(last);
1239 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 1240 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1240 } 1241 }
1241 1242
1242 HandlerFrontendFooter(name, &miss); 1243 HandlerFrontendFooter(name, &miss);
1243 } 1244 }
1244 1245
1245 1246
1246 Handle<Code> LoadStubCompiler::CompileLoadField( 1247 Handle<Code> LoadStubCompiler::CompileLoadField(
1247 Handle<Object> object, 1248 Handle<Type> type,
1248 Handle<JSObject> holder, 1249 Handle<JSObject> holder,
1249 Handle<Name> name, 1250 Handle<Name> name,
1250 PropertyIndex field, 1251 PropertyIndex field,
1251 Representation representation) { 1252 Representation representation) {
1252 Label miss; 1253 Label miss;
1253 1254
1254 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); 1255 Register reg = HandlerFrontendHeader(type, receiver(), holder, name, &miss);
1255 1256
1256 GenerateLoadField(reg, holder, field, representation); 1257 GenerateLoadField(reg, holder, field, representation);
1257 1258
1258 __ bind(&miss); 1259 __ bind(&miss);
1259 TailCallBuiltin(masm(), MissBuiltin(kind())); 1260 TailCallBuiltin(masm(), MissBuiltin(kind()));
1260 1261
1261 // Return the generated code. 1262 // Return the generated code.
1262 return GetCode(kind(), Code::FAST, name); 1263 return GetCode(kind(), Code::FAST, name);
1263 } 1264 }
1264 1265
1265 1266
1266 Handle<Code> LoadStubCompiler::CompileLoadConstant( 1267 Handle<Code> LoadStubCompiler::CompileLoadConstant(
1267 Handle<Object> object, 1268 Handle<Type> type,
1268 Handle<JSObject> holder, 1269 Handle<JSObject> holder,
1269 Handle<Name> name, 1270 Handle<Name> name,
1270 Handle<Object> value) { 1271 Handle<Object> value) {
1271 HandlerFrontend(object, receiver(), holder, name); 1272 HandlerFrontend(type, receiver(), holder, name);
1272 GenerateLoadConstant(value); 1273 GenerateLoadConstant(value);
1273 1274
1274 // Return the generated code. 1275 // Return the generated code.
1275 return GetCode(kind(), Code::FAST, name); 1276 return GetCode(kind(), Code::FAST, name);
1276 } 1277 }
1277 1278
1278 1279
1279 Handle<Code> LoadStubCompiler::CompileLoadCallback( 1280 Handle<Code> LoadStubCompiler::CompileLoadCallback(
1280 Handle<Object> object, 1281 Handle<Type> type,
1281 Handle<JSObject> holder, 1282 Handle<JSObject> holder,
1282 Handle<Name> name, 1283 Handle<Name> name,
1283 Handle<ExecutableAccessorInfo> callback) { 1284 Handle<ExecutableAccessorInfo> callback) {
1284 Register reg = CallbackHandlerFrontend( 1285 Register reg = CallbackHandlerFrontend(
1285 object, receiver(), holder, name, callback); 1286 type, receiver(), holder, name, callback);
1286 GenerateLoadCallback(reg, callback); 1287 GenerateLoadCallback(reg, callback);
1287 1288
1288 // Return the generated code. 1289 // Return the generated code.
1289 return GetCode(kind(), Code::FAST, name); 1290 return GetCode(kind(), Code::FAST, name);
1290 } 1291 }
1291 1292
1292 1293
1293 Handle<Code> LoadStubCompiler::CompileLoadCallback( 1294 Handle<Code> LoadStubCompiler::CompileLoadCallback(
1294 Handle<Object> object, 1295 Handle<Type> type,
1295 Handle<JSObject> holder, 1296 Handle<JSObject> holder,
1296 Handle<Name> name, 1297 Handle<Name> name,
1297 const CallOptimization& call_optimization) { 1298 const CallOptimization& call_optimization) {
1298 ASSERT(call_optimization.is_simple_api_call()); 1299 ASSERT(call_optimization.is_simple_api_call());
1299 Handle<JSFunction> callback = call_optimization.constant_function(); 1300 Handle<JSFunction> callback = call_optimization.constant_function();
1300 CallbackHandlerFrontend(object, receiver(), holder, name, callback); 1301 CallbackHandlerFrontend(type, receiver(), holder, name, callback);
1301 GenerateLoadCallback(call_optimization); 1302 GenerateLoadCallback(call_optimization);
1302 1303
1303 // Return the generated code. 1304 // Return the generated code.
1304 return GetCode(kind(), Code::FAST, name); 1305 return GetCode(kind(), Code::FAST, name);
1305 } 1306 }
1306 1307
1307 1308
1308 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( 1309 Handle<Code> LoadStubCompiler::CompileLoadInterceptor(
1309 Handle<Object> object, 1310 Handle<Type> type,
1310 Handle<JSObject> holder, 1311 Handle<JSObject> holder,
1311 Handle<Name> name) { 1312 Handle<Name> name) {
1312 LookupResult lookup(isolate()); 1313 LookupResult lookup(isolate());
1313 LookupPostInterceptor(holder, name, &lookup); 1314 LookupPostInterceptor(holder, name, &lookup);
1314 1315
1315 Register reg = HandlerFrontend(object, receiver(), holder, name); 1316 Register reg = HandlerFrontend(type, receiver(), holder, name);
1316 // TODO(368): Compile in the whole chain: all the interceptors in 1317 // TODO(368): Compile in the whole chain: all the interceptors in
1317 // prototypes and ultimate answer. 1318 // prototypes and ultimate answer.
1318 GenerateLoadInterceptor(reg, object, holder, &lookup, name); 1319 GenerateLoadInterceptor(reg, type, holder, &lookup, name);
1319 1320
1320 // Return the generated code. 1321 // Return the generated code.
1321 return GetCode(kind(), Code::FAST, name); 1322 return GetCode(kind(), Code::FAST, name);
1322 } 1323 }
1323 1324
1324 1325
1325 void LoadStubCompiler::GenerateLoadPostInterceptor( 1326 void LoadStubCompiler::GenerateLoadPostInterceptor(
1326 Register interceptor_reg, 1327 Register interceptor_reg,
1327 Handle<JSObject> interceptor_holder, 1328 Handle<JSObject> interceptor_holder,
1328 Handle<Name> name, 1329 Handle<Name> name,
1329 LookupResult* lookup) { 1330 LookupResult* lookup) {
1330 Handle<JSObject> holder(lookup->holder()); 1331 Handle<JSObject> holder(lookup->holder());
1331 if (lookup->IsField()) { 1332 if (lookup->IsField()) {
1332 PropertyIndex field = lookup->GetFieldIndex(); 1333 PropertyIndex field = lookup->GetFieldIndex();
1333 if (interceptor_holder.is_identical_to(holder)) { 1334 if (interceptor_holder.is_identical_to(holder)) {
1334 GenerateLoadField( 1335 GenerateLoadField(
1335 interceptor_reg, holder, field, lookup->representation()); 1336 interceptor_reg, holder, field, lookup->representation());
1336 } else { 1337 } else {
1337 // We found FIELD property in prototype chain of interceptor's holder. 1338 // We found FIELD property in prototype chain of interceptor's holder.
1338 // Retrieve a field from field's holder. 1339 // Retrieve a field from field's holder.
1339 Register reg = HandlerFrontend( 1340 Register reg = HandlerFrontend(
1340 interceptor_holder, interceptor_reg, holder, name); 1341 IC::CurrentTypeOf(interceptor_holder, isolate()),
1342 interceptor_reg, holder, name);
1341 GenerateLoadField( 1343 GenerateLoadField(
1342 reg, holder, field, lookup->representation()); 1344 reg, holder, field, lookup->representation());
1343 } 1345 }
1344 } else { 1346 } else {
1345 // We found CALLBACKS property in prototype chain of interceptor's 1347 // We found CALLBACKS property in prototype chain of interceptor's
1346 // holder. 1348 // holder.
1347 ASSERT(lookup->type() == CALLBACKS); 1349 ASSERT(lookup->type() == CALLBACKS);
1348 Handle<ExecutableAccessorInfo> callback( 1350 Handle<ExecutableAccessorInfo> callback(
1349 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 1351 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
1350 ASSERT(callback->getter() != NULL); 1352 ASSERT(callback->getter() != NULL);
1351 1353
1352 Register reg = CallbackHandlerFrontend( 1354 Register reg = CallbackHandlerFrontend(
1353 interceptor_holder, interceptor_reg, holder, name, callback); 1355 IC::CurrentTypeOf(interceptor_holder, isolate()),
1356 interceptor_reg, holder, name, callback);
1354 GenerateLoadCallback(reg, callback); 1357 GenerateLoadCallback(reg, callback);
1355 } 1358 }
1356 } 1359 }
1357 1360
1358 1361
1359 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC( 1362 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC(
1360 Handle<Type> type, 1363 Handle<Type> type,
1361 Handle<Code> handler, 1364 Handle<Code> handler,
1362 Handle<Name> name) { 1365 Handle<Name> name) {
1363 TypeHandleList types(1); 1366 TypeHandleList types(1);
1364 CodeHandleList handlers(1); 1367 CodeHandleList handlers(1);
1365 types.Add(type); 1368 types.Add(type);
1366 handlers.Add(handler); 1369 handlers.Add(handler);
1367 Code::StubType stub_type = handler->type(); 1370 Code::StubType stub_type = handler->type();
1368 return CompilePolymorphicIC(&types, &handlers, name, stub_type, PROPERTY); 1371 return CompilePolymorphicIC(&types, &handlers, name, stub_type, PROPERTY);
1369 } 1372 }
1370 1373
1371 1374
1372 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( 1375 Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
1373 Handle<Object> object, 1376 Handle<Type> type,
1374 Handle<JSObject> holder, 1377 Handle<JSObject> holder,
1375 Handle<Name> name, 1378 Handle<Name> name,
1376 Handle<JSFunction> getter) { 1379 Handle<JSFunction> getter) {
1377 HandlerFrontend(object, receiver(), holder, name); 1380 HandlerFrontend(type, receiver(), holder, name);
1378 GenerateLoadViaGetter(masm(), receiver(), getter); 1381 GenerateLoadViaGetter(masm(), receiver(), getter);
1379 1382
1380 // Return the generated code. 1383 // Return the generated code.
1381 return GetCode(kind(), Code::FAST, name); 1384 return GetCode(kind(), Code::FAST, name);
1382 } 1385 }
1383 1386
1384 1387
1385 Handle<Code> StoreStubCompiler::CompileStoreTransition( 1388 Handle<Code> StoreStubCompiler::CompileStoreTransition(
1386 Handle<JSObject> object, 1389 Handle<JSObject> object,
1387 LookupResult* lookup, 1390 LookupResult* lookup,
(...skipping 11 matching lines...) Expand all
1399 if (lookup->holder() != *object) { 1402 if (lookup->holder() != *object) {
1400 holder = Handle<JSObject>(lookup->holder()); 1403 holder = Handle<JSObject>(lookup->holder());
1401 } else { 1404 } else {
1402 // Find the top object. 1405 // Find the top object.
1403 holder = object; 1406 holder = object;
1404 do { 1407 do {
1405 holder = Handle<JSObject>(JSObject::cast(holder->GetPrototype())); 1408 holder = Handle<JSObject>(JSObject::cast(holder->GetPrototype()));
1406 } while (holder->GetPrototype()->IsJSObject()); 1409 } while (holder->GetPrototype()->IsJSObject());
1407 } 1410 }
1408 1411
1409 Register holder_reg = 1412 Register holder_reg = HandlerFrontendHeader(
1410 HandlerFrontendHeader(object, receiver(), holder, name, &miss); 1413 IC::CurrentTypeOf(object, isolate()), receiver(), holder, name, &miss);
1411 1414
1412 // If no property was found, and the holder (the last object in the 1415 // If no property was found, and the holder (the last object in the
1413 // prototype chain) is in slow mode, we need to do a negative lookup on the 1416 // prototype chain) is in slow mode, we need to do a negative lookup on the
1414 // holder. 1417 // holder.
1415 if (lookup->holder() == *object) { 1418 if (lookup->holder() == *object) {
1416 GenerateNegativeHolderLookup(masm(), holder, holder_reg, name, &miss); 1419 GenerateNegativeHolderLookup(masm(), holder, holder_reg, name, &miss);
1417 } 1420 }
1418 } 1421 }
1419 1422
1420 GenerateStoreTransition(masm(), 1423 GenerateStoreTransition(masm(),
(...skipping 16 matching lines...) Expand all
1437 // Return the generated code. 1440 // Return the generated code.
1438 return GetCode(kind(), Code::FAST, name); 1441 return GetCode(kind(), Code::FAST, name);
1439 } 1442 }
1440 1443
1441 1444
1442 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, 1445 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
1443 LookupResult* lookup, 1446 LookupResult* lookup,
1444 Handle<Name> name) { 1447 Handle<Name> name) {
1445 Label miss; 1448 Label miss;
1446 1449
1447 HandlerFrontendHeader(object, receiver(), object, name, &miss); 1450 HandlerFrontendHeader(IC::CurrentTypeOf(object, isolate()),
1451 receiver(), object, name, &miss);
1448 1452
1449 // Generate store field code. 1453 // Generate store field code.
1450 GenerateStoreField(masm(), 1454 GenerateStoreField(masm(),
1451 object, 1455 object,
1452 lookup, 1456 lookup,
1453 receiver(), this->name(), value(), scratch1(), scratch2(), 1457 receiver(), this->name(), value(), scratch1(), scratch2(),
1454 &miss); 1458 &miss);
1455 1459
1456 // Handle store cache miss. 1460 // Handle store cache miss.
1457 __ bind(&miss); 1461 __ bind(&miss);
1458 TailCallBuiltin(masm(), MissBuiltin(kind())); 1462 TailCallBuiltin(masm(), MissBuiltin(kind()));
1459 1463
1460 // Return the generated code. 1464 // Return the generated code.
1461 return GetCode(kind(), Code::FAST, name); 1465 return GetCode(kind(), Code::FAST, name);
1462 } 1466 }
1463 1467
1464 1468
1465 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( 1469 Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
1466 Handle<JSObject> object, 1470 Handle<JSObject> object,
1467 Handle<JSObject> holder, 1471 Handle<JSObject> holder,
1468 Handle<Name> name, 1472 Handle<Name> name,
1469 Handle<JSFunction> setter) { 1473 Handle<JSFunction> setter) {
1470 HandlerFrontend(object, receiver(), holder, name); 1474 HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
1475 receiver(), holder, name);
1471 GenerateStoreViaSetter(masm(), setter); 1476 GenerateStoreViaSetter(masm(), setter);
1472 1477
1473 return GetCode(kind(), Code::FAST, name); 1478 return GetCode(kind(), Code::FAST, name);
1474 } 1479 }
1475 1480
1476 1481
1477 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( 1482 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
1478 Handle<Map> receiver_map) { 1483 Handle<Map> receiver_map) {
1479 ElementsKind elements_kind = receiver_map->elements_kind(); 1484 ElementsKind elements_kind = receiver_map->elements_kind();
1480 if (receiver_map->has_fast_elements() || 1485 if (receiver_map->has_fast_elements() ||
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
1828 Handle<FunctionTemplateInfo>( 1833 Handle<FunctionTemplateInfo>(
1829 FunctionTemplateInfo::cast(signature->receiver())); 1834 FunctionTemplateInfo::cast(signature->receiver()));
1830 } 1835 }
1831 } 1836 }
1832 1837
1833 is_simple_api_call_ = true; 1838 is_simple_api_call_ = true;
1834 } 1839 }
1835 1840
1836 1841
1837 } } // namespace v8::internal 1842 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698