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

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

Issue 12340112: Polymorphism support for load IC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 months 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
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 93
94 // Update primary cache. 94 // Update primary cache.
95 primary->key = name; 95 primary->key = name;
96 primary->value = code; 96 primary->value = code;
97 primary->map = map; 97 primary->map = map;
98 isolate()->counters()->megamorphic_stub_cache_updates()->Increment(); 98 isolate()->counters()->megamorphic_stub_cache_updates()->Increment();
99 return code; 99 return code;
100 } 100 }
101 101
102 102
103 Handle<JSObject> StubCache::StubHolder(Handle<JSObject> receiver,
104 Handle<JSObject> holder) {
105 InlineCacheHolderFlag cache_holder =
106 IC::GetCodeCacheForObject(*receiver, *holder);
107 return Handle<JSObject>(IC::GetCodeCacheHolder(
108 isolate_, *receiver, cache_holder));
109 }
110
Jakob Kummerow 2013/03/01 22:21:04 nit: two empty lines
Toon Verwaest 2013/03/04 10:54:08 Done.
111 Handle<Code> StubCache::FindStub(Handle<String> name,
112 Handle<JSObject> stub_holder,
113 Code::Kind kind,
114 Code::StubType type,
115 Code::IcFragment fragment) {
116 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, fragment, type);
117 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
118 isolate_);
119 if (probe->IsCode()) return Handle<Code>::cast(probe);
120 return Handle<Code>::null();
121 }
122
123
124 Handle<Code> StubCache::FindHandler(Handle<String> name,
125 Handle<JSObject> handler_holder,
126 Code::Kind kind,
127 Code::StubType type) {
128 return FindStub(name, handler_holder, kind, type, Code::HANDLER_FRAGMENT);
129 }
130
131
132 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<JSObject> receiver,
133 Handle<Code> handler,
134 Handle<String> name) {
135 Handle<Code> ic = FindStub(name, receiver, Code::LOAD_IC,
136 handler->type(), Code::IC_FRAGMENT);
137 if (!ic.is_null()) return ic;
138
139 LoadStubCompiler ic_compiler(isolate());
140 ic = ic_compiler.CompileMonomorphicIC(
141 Handle<Map>(receiver->map()), handler, name);
142
143 JSObject::UpdateMapCodeCache(receiver, name, ic);
144 return ic;
145 }
146
147
148 Handle<Code> StubCache::ComputeKeyedMonomorphicIC(Handle<JSObject> receiver,
149 Handle<Code> handler,
150 Handle<String> name) {
151 Handle<Code> ic = FindStub(name, receiver, Code::KEYED_LOAD_IC,
152 handler->type(), Code::IC_FRAGMENT);
153 if (!ic.is_null()) return ic;
154
155 KeyedLoadStubCompiler ic_compiler(isolate());
156 ic = ic_compiler.CompileMonomorphicIC(
157 Handle<Map>(receiver->map()), handler, name);
158
159 JSObject::UpdateMapCodeCache(receiver, name, ic);
160 return ic;
161 }
162
163
103 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name, 164 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name,
104 Handle<JSObject> receiver) { 165 Handle<JSObject> receiver) {
105 // If no global objects are present in the prototype chain, the load 166 // If no global objects are present in the prototype chain, the load
106 // nonexistent IC stub can be shared for all names for a given map 167 // nonexistent IC stub can be shared for all names for a given map
107 // and we use the empty string for the map cache in that case. If 168 // and we use the empty string for the map cache in that case. If
108 // there are global objects involved, we need to check global 169 // there are global objects involved, we need to check global
109 // property cells in the stub and therefore the stub will be 170 // property cells in the stub and therefore the stub will be
110 // specific to the name. 171 // specific to the name.
111 Handle<String> cache_name = factory()->empty_string(); 172 Handle<String> cache_name = factory()->empty_string();
112 Handle<JSObject> current; 173 Handle<JSObject> current;
113 Handle<Object> next = receiver; 174 Handle<Object> next = receiver;
114 Handle<GlobalObject> global; 175 Handle<GlobalObject> global;
115 do { 176 do {
116 current = Handle<JSObject>::cast(next); 177 current = Handle<JSObject>::cast(next);
117 next = Handle<Object>(current->GetPrototype(), isolate_); 178 next = Handle<Object>(current->GetPrototype(), isolate_);
118 if (current->IsGlobalObject()) { 179 if (current->IsGlobalObject()) {
119 global = Handle<GlobalObject>::cast(current); 180 global = Handle<GlobalObject>::cast(current);
120 cache_name = name; 181 cache_name = name;
121 } else if (!current->HasFastProperties()) { 182 } else if (!current->HasFastProperties()) {
122 cache_name = name; 183 cache_name = name;
123 } 184 }
124 } while (!next->IsNull()); 185 } while (!next->IsNull());
125 186
126 // Compile the stub that is either shared for all names or 187 // Compile the stub that is either shared for all names or
127 // name specific if there are global objects involved. 188 // name specific if there are global objects involved.
128 Code::Flags flags = Code::ComputeMonomorphicFlags( 189 Handle<Code> handler = FindHandler(
129 Code::LOAD_IC, Code::kNoExtraICState, Code::NONEXISTENT); 190 cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT);
130 Handle<Object> probe(receiver->map()->FindInCodeCache(*cache_name, flags), 191 if (!handler.is_null()) return handler;
131 isolate_);
132 if (probe->IsCode()) return Handle<Code>::cast(probe);
133 192
134 LoadStubCompiler compiler(isolate_); 193 LoadStubCompiler compiler(isolate_);
135 Handle<Code> code = 194 handler =
136 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); 195 compiler.CompileLoadNonexistent(receiver, current, cache_name, global);
137 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name)); 196 JSObject::UpdateMapCodeCache(receiver, cache_name, handler);
138 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code)); 197 return handler;
139 JSObject::UpdateMapCodeCache(receiver, cache_name, code);
140 return code;
141 } 198 }
142 199
143 200
144 Handle<Code> StubCache::ComputeLoadField(Handle<String> name, 201 Handle<Code> StubCache::ComputeLoadField(Handle<String> name,
145 Handle<JSObject> receiver, 202 Handle<JSObject> receiver,
146 Handle<JSObject> holder, 203 Handle<JSObject> holder,
147 PropertyIndex field) { 204 PropertyIndex field) {
148 InlineCacheHolderFlag cache_holder = 205 if (receiver.is_identical_to(holder)) {
149 IC::GetCodeCacheForObject(*receiver, *holder); 206 LoadFieldStub stub(LoadStubCompiler::receiver(),
150 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 207 field.is_inobject(holder),
151 isolate_, *receiver, cache_holder)); 208 field.translate(holder));
152 Code::Flags flags = Code::ComputeMonomorphicFlags( 209 return stub.GetCode(isolate());
153 Code::LOAD_IC, Code::kNoExtraICState, Code::FIELD); 210 }
154 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), 211
155 isolate_); 212 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
156 if (probe->IsCode()) return Handle<Code>::cast(probe); 213 Handle<Code> stub = FindHandler(
214 name, stub_holder, Code::LOAD_IC, Code::FIELD);
215 if (!stub.is_null()) return stub;
157 216
158 LoadStubCompiler compiler(isolate_); 217 LoadStubCompiler compiler(isolate_);
159 Handle<Code> code = compiler.CompileLoadField(receiver, holder, name, field); 218 Handle<Code> handler =
160 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 219 compiler.CompileLoadField(receiver, holder, name, field);
161 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 220 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
162 JSObject::UpdateMapCodeCache(map_holder, name, code); 221 return handler;
163 return code;
164 } 222 }
165 223
166 224
167 Handle<Code> StubCache::ComputeLoadCallback( 225 Handle<Code> StubCache::ComputeLoadCallback(
168 Handle<String> name, 226 Handle<String> name,
169 Handle<JSObject> receiver, 227 Handle<JSObject> receiver,
170 Handle<JSObject> holder, 228 Handle<JSObject> holder,
171 Handle<ExecutableAccessorInfo> callback) { 229 Handle<ExecutableAccessorInfo> callback) {
172 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); 230 ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
173 InlineCacheHolderFlag cache_holder = 231 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
174 IC::GetCodeCacheForObject(*receiver, *holder); 232 Handle<Code> stub = FindHandler(
175 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 233 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
176 isolate_, *receiver, cache_holder)); 234 if (!stub.is_null()) return stub;
177 Code::Flags flags = Code::ComputeMonomorphicFlags(
178 Code::LOAD_IC, Code::kNoExtraICState, Code::CALLBACKS);
179 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
180 isolate_);
181 if (probe->IsCode()) return Handle<Code>::cast(probe);
182 235
183 LoadStubCompiler compiler(isolate_); 236 LoadStubCompiler compiler(isolate_);
184 Handle<Code> code = 237 Handle<Code> handler =
185 compiler.CompileLoadCallback(receiver, holder, name, callback); 238 compiler.CompileLoadCallback(receiver, holder, name, callback);
186 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 239 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
187 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 240 return handler;
188 JSObject::UpdateMapCodeCache(map_holder, name, code);
189 return code;
190 } 241 }
191 242
192 243
193 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<String> name, 244 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<String> name,
194 Handle<JSObject> receiver, 245 Handle<JSObject> receiver,
195 Handle<JSObject> holder, 246 Handle<JSObject> holder,
196 Handle<JSFunction> getter) { 247 Handle<JSFunction> getter) {
197 InlineCacheHolderFlag cache_holder = 248 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
198 IC::GetCodeCacheForObject(*receiver, *holder); 249 Handle<Code> stub = FindHandler(
199 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 250 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
200 isolate_, *receiver, cache_holder)); 251 if (!stub.is_null()) return stub;
201 Code::Flags flags = Code::ComputeMonomorphicFlags(
202 Code::LOAD_IC, Code::kNoExtraICState, Code::CALLBACKS);
203 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
204 isolate_);
205 if (probe->IsCode()) return Handle<Code>::cast(probe);
206 252
207 LoadStubCompiler compiler(isolate_); 253 LoadStubCompiler compiler(isolate_);
208 Handle<Code> code = 254 Handle<Code> handler =
209 compiler.CompileLoadViaGetter(receiver, holder, name, getter); 255 compiler.CompileLoadViaGetter(receiver, holder, name, getter);
210 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 256 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
211 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 257 return handler;
212 JSObject::UpdateMapCodeCache(map_holder, name, code);
213 return code;
214 } 258 }
215 259
216 260
217 Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name, 261 Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name,
218 Handle<JSObject> receiver, 262 Handle<JSObject> receiver,
219 Handle<JSObject> holder, 263 Handle<JSObject> holder,
220 Handle<JSFunction> value) { 264 Handle<JSFunction> value) {
221 InlineCacheHolderFlag cache_holder = 265 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
222 IC::GetCodeCacheForObject(*receiver, *holder); 266 Handle<Code> handler = FindHandler(
223 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 267 name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION);
224 isolate_, *receiver, cache_holder)); 268 if (!handler.is_null()) return handler;
225 Code::Flags flags = Code::ComputeMonomorphicFlags(
226 Code::LOAD_IC, Code::kNoExtraICState, Code::CONSTANT_FUNCTION);
227 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
228 isolate_);
229 if (probe->IsCode()) return Handle<Code>::cast(probe);
230 269
231 LoadStubCompiler compiler(isolate_); 270 LoadStubCompiler compiler(isolate_);
232 Handle<Code> code = 271 handler = compiler.CompileLoadConstant(receiver, holder, name, value);
233 compiler.CompileLoadConstant(receiver, holder, name, value); 272 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
234 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 273
235 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 274 return handler;
236 JSObject::UpdateMapCodeCache(map_holder, name, code);
237 return code;
238 } 275 }
239 276
240 277
241 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name, 278 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name,
242 Handle<JSObject> receiver, 279 Handle<JSObject> receiver,
243 Handle<JSObject> holder) { 280 Handle<JSObject> holder) {
244 InlineCacheHolderFlag cache_holder = 281 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
245 IC::GetCodeCacheForObject(*receiver, *holder); 282 Handle<Code> stub = FindHandler(
246 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 283 name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR);
247 isolate_, *receiver, cache_holder)); 284 if (!stub.is_null()) return stub;
248 Code::Flags flags = Code::ComputeMonomorphicFlags(
249 Code::LOAD_IC, Code::kNoExtraICState, Code::INTERCEPTOR);
250 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
251 isolate_);
252 if (probe->IsCode()) return Handle<Code>::cast(probe);
253 285
254 LoadStubCompiler compiler(isolate_); 286 LoadStubCompiler compiler(isolate_);
255 Handle<Code> code = 287 Handle<Code> handler =
256 compiler.CompileLoadInterceptor(receiver, holder, name); 288 compiler.CompileLoadInterceptor(receiver, holder, name);
257 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 289 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
258 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 290 return handler;
259 JSObject::UpdateMapCodeCache(map_holder, name, code);
260 return code;
261 } 291 }
262 292
263 293
264 Handle<Code> StubCache::ComputeLoadNormal() { 294 Handle<Code> StubCache::ComputeLoadNormal(Handle<String> name,
295 Handle<JSObject> receiver) {
265 return isolate_->builtins()->LoadIC_Normal(); 296 return isolate_->builtins()->LoadIC_Normal();
266 } 297 }
267 298
268 299
269 Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name, 300 Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name,
270 Handle<JSObject> receiver, 301 Handle<JSObject> receiver,
271 Handle<GlobalObject> holder, 302 Handle<GlobalObject> holder,
272 Handle<JSGlobalPropertyCell> cell, 303 Handle<JSGlobalPropertyCell> cell,
273 bool is_dont_delete) { 304 bool is_dont_delete) {
274 InlineCacheHolderFlag cache_holder = 305 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
275 IC::GetCodeCacheForObject(*receiver, *holder); 306 Handle<Code> stub = FindStub(
276 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 307 name, stub_holder, Code::LOAD_IC, Code::NORMAL, Code::IC_FRAGMENT);
277 isolate_, *receiver, cache_holder)); 308 if (!stub.is_null()) return stub;
278 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC);
279 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
280 isolate_);
281 if (probe->IsCode()) return Handle<Code>::cast(probe);
282 309
283 LoadStubCompiler compiler(isolate_); 310 LoadStubCompiler compiler(isolate_);
284 Handle<Code> code = 311 Handle<Code> ic =
285 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); 312 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete);
286 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 313 JSObject::UpdateMapCodeCache(stub_holder, name, ic);
287 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 314 return ic;
288 JSObject::UpdateMapCodeCache(map_holder, name, code);
289 return code;
290 } 315 }
291 316
292 317
293 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name, 318 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name,
294 Handle<JSObject> receiver, 319 Handle<JSObject> receiver,
295 Handle<JSObject> holder, 320 Handle<JSObject> holder,
296 PropertyIndex field) { 321 PropertyIndex field) {
297 InlineCacheHolderFlag cache_holder = 322 if (receiver.is_identical_to(holder)) {
298 IC::GetCodeCacheForObject(*receiver, *holder); 323 LoadFieldStub stub(KeyedLoadStubCompiler::receiver(),
299 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 324 field.is_inobject(holder),
300 isolate_, *receiver, cache_holder)); 325 field.translate(holder));
301 Code::Flags flags = Code::ComputeMonomorphicFlags( 326 return stub.GetCode(isolate());
302 Code::KEYED_LOAD_IC, Code::kNoExtraICState, Code::FIELD); 327 }
303 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), 328
304 isolate_); 329 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
305 if (probe->IsCode()) return Handle<Code>::cast(probe); 330 Handle<Code> stub = FindHandler(
331 name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD);
332 if (!stub.is_null()) return stub;
306 333
307 KeyedLoadStubCompiler compiler(isolate_); 334 KeyedLoadStubCompiler compiler(isolate_);
308 Handle<Code> code = compiler.CompileLoadField(receiver, holder, name, field); 335 Handle<Code> handler =
309 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 336 compiler.CompileLoadField(receiver, holder, name, field);
310 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 337 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
311 JSObject::UpdateMapCodeCache(map_holder, name, code); 338 return handler;
312 return code;
313 } 339 }
314 340
315 341
316 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name, 342 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name,
317 Handle<JSObject> receiver, 343 Handle<JSObject> receiver,
318 Handle<JSObject> holder, 344 Handle<JSObject> holder,
319 Handle<JSFunction> value) { 345 Handle<JSFunction> value) {
320 InlineCacheHolderFlag cache_holder = 346 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
321 IC::GetCodeCacheForObject(*receiver, *holder); 347 Handle<Code> handler = FindHandler(
322 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 348 name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION);
323 isolate_, *receiver, cache_holder)); 349 if (!handler.is_null()) return handler;
324 Code::Flags flags = Code::ComputeMonomorphicFlags(
325 Code::KEYED_LOAD_IC, Code::kNoExtraICState, Code::CONSTANT_FUNCTION);
326 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
327 isolate_);
328 if (probe->IsCode()) return Handle<Code>::cast(probe);
329 350
330 KeyedLoadStubCompiler compiler(isolate_); 351 KeyedLoadStubCompiler compiler(isolate_);
331 Handle<Code> code = 352 handler = compiler.CompileLoadConstant(receiver, holder, name, value);
332 compiler.CompileLoadConstant(receiver, holder, name, value); 353 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
333 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 354 return handler;
334 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
335 JSObject::UpdateMapCodeCache(map_holder, name, code);
336 return code;
337 } 355 }
338 356
339 357
340 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name, 358 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name,
341 Handle<JSObject> receiver, 359 Handle<JSObject> receiver,
342 Handle<JSObject> holder) { 360 Handle<JSObject> holder) {
343 InlineCacheHolderFlag cache_holder = 361 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
344 IC::GetCodeCacheForObject(*receiver, *holder); 362 Handle<Code> stub = FindHandler(
345 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 363 name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
346 isolate_, *receiver, cache_holder)); 364 if (!stub.is_null()) return stub;
347 Code::Flags flags = Code::ComputeMonomorphicFlags(
348 Code::KEYED_LOAD_IC, Code::kNoExtraICState, Code::INTERCEPTOR);
349 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
350 isolate_);
351 if (probe->IsCode()) return Handle<Code>::cast(probe);
352 365
353 KeyedLoadStubCompiler compiler(isolate_); 366 KeyedLoadStubCompiler compiler(isolate_);
354 Handle<Code> code = compiler.CompileLoadInterceptor(receiver, holder, name); 367 Handle<Code> handler =
355 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 368 compiler.CompileLoadInterceptor(receiver, holder, name);
356 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 369 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
357 JSObject::UpdateMapCodeCache(map_holder, name, code); 370 return handler;
358 return code;
359 } 371 }
360 372
361 373
362 Handle<Code> StubCache::ComputeKeyedLoadCallback( 374 Handle<Code> StubCache::ComputeKeyedLoadCallback(
363 Handle<String> name, 375 Handle<String> name,
364 Handle<JSObject> receiver, 376 Handle<JSObject> receiver,
365 Handle<JSObject> holder, 377 Handle<JSObject> holder,
366 Handle<ExecutableAccessorInfo> callback) { 378 Handle<ExecutableAccessorInfo> callback) {
367 InlineCacheHolderFlag cache_holder = 379 Handle<JSObject> stub_holder = StubHolder(receiver, holder);
368 IC::GetCodeCacheForObject(*receiver, *holder); 380 Handle<Code> stub = FindHandler(
369 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 381 name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS);
370 isolate_, *receiver, cache_holder)); 382 if (!stub.is_null()) return stub;
371 Code::Flags flags = Code::ComputeMonomorphicFlags(
372 Code::KEYED_LOAD_IC, Code::kNoExtraICState, Code::CALLBACKS);
373 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags),
374 isolate_);
375 if (probe->IsCode()) return Handle<Code>::cast(probe);
376 383
377 KeyedLoadStubCompiler compiler(isolate_); 384 KeyedLoadStubCompiler compiler(isolate_);
378 Handle<Code> code = 385 Handle<Code> handler =
379 compiler.CompileLoadCallback(receiver, holder, name, callback); 386 compiler.CompileLoadCallback(receiver, holder, name, callback);
380 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 387 JSObject::UpdateMapCodeCache(stub_holder, name, handler);
381 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 388 return handler;
382 JSObject::UpdateMapCodeCache(map_holder, name, code);
383 return code;
384 } 389 }
385 390
386 391
387 Handle<Code> StubCache::ComputeStoreField(Handle<String> name, 392 Handle<Code> StubCache::ComputeStoreField(Handle<String> name,
388 Handle<JSObject> receiver, 393 Handle<JSObject> receiver,
389 int field_index, 394 int field_index,
390 Handle<Map> transition, 395 Handle<Map> transition,
391 StrictModeFlag strict_mode) { 396 StrictModeFlag strict_mode) {
392 Code::StubType type = 397 Code::StubType type =
393 (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION; 398 (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION;
394 Code::Flags flags = Code::ComputeMonomorphicFlags( 399 Code::Flags flags = Code::ComputeMonomorphicFlags(
395 Code::STORE_IC, strict_mode, type); 400 Code::STORE_IC, strict_mode, type);
396 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 401 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
397 isolate_); 402 isolate_);
398 if (probe->IsCode()) return Handle<Code>::cast(probe); 403 if (probe->IsCode()) return Handle<Code>::cast(probe);
399 404
400 StoreStubCompiler compiler(isolate_, strict_mode); 405 StoreStubCompiler compiler(isolate_, strict_mode);
401 Handle<Code> code = 406 Handle<Code> code =
402 compiler.CompileStoreField(receiver, field_index, transition, name); 407 compiler.CompileStoreField(receiver, field_index, transition, name);
403 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
404 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
405 JSObject::UpdateMapCodeCache(receiver, name, code); 408 JSObject::UpdateMapCodeCache(receiver, name, code);
406 return code; 409 return code;
407 } 410 }
408 411
409 412
410 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { 413 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) {
411 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); 414 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
412 Handle<String> name = 415 Handle<String> name =
413 isolate()->factory()->KeyedLoadElementMonomorphic_symbol(); 416 isolate()->factory()->KeyedLoadElementMonomorphic_symbol();
414 417
415 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); 418 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_);
416 if (probe->IsCode()) return Handle<Code>::cast(probe); 419 if (probe->IsCode()) return Handle<Code>::cast(probe);
417 420
418 KeyedLoadStubCompiler compiler(isolate()); 421 KeyedLoadStubCompiler compiler(isolate());
419 Handle<Code> code = compiler.CompileLoadElement(receiver_map); 422 Handle<Code> code = compiler.CompileLoadElement(receiver_map);
420 423
421 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, 0));
422 Map::UpdateCodeCache(receiver_map, name, code); 424 Map::UpdateCodeCache(receiver_map, name, code);
423 return code; 425 return code;
424 } 426 }
425 427
426 428
427 Handle<Code> StubCache::ComputeKeyedStoreElement( 429 Handle<Code> StubCache::ComputeKeyedStoreElement(
428 Handle<Map> receiver_map, 430 Handle<Map> receiver_map,
429 KeyedStoreIC::StubKind stub_kind, 431 KeyedStoreIC::StubKind stub_kind,
430 StrictModeFlag strict_mode, 432 StrictModeFlag strict_mode,
431 KeyedAccessGrowMode grow_mode) { 433 KeyedAccessGrowMode grow_mode) {
432 Code::ExtraICState extra_state = 434 Code::ExtraICState extra_state =
433 Code::ComputeExtraICState(grow_mode, strict_mode); 435 Code::ComputeExtraICState(grow_mode, strict_mode);
434 Code::Flags flags = Code::ComputeMonomorphicFlags( 436 Code::Flags flags = Code::ComputeMonomorphicFlags(
435 Code::KEYED_STORE_IC, extra_state); 437 Code::KEYED_STORE_IC, extra_state);
436 438
437 ASSERT(stub_kind == KeyedStoreIC::STORE_NO_TRANSITION || 439 ASSERT(stub_kind == KeyedStoreIC::STORE_NO_TRANSITION ||
438 stub_kind == KeyedStoreIC::STORE_AND_GROW_NO_TRANSITION); 440 stub_kind == KeyedStoreIC::STORE_AND_GROW_NO_TRANSITION);
439 441
440 Handle<String> name = stub_kind == KeyedStoreIC::STORE_NO_TRANSITION 442 Handle<String> name = stub_kind == KeyedStoreIC::STORE_NO_TRANSITION
441 ? isolate()->factory()->KeyedStoreElementMonomorphic_symbol() 443 ? isolate()->factory()->KeyedStoreElementMonomorphic_symbol()
442 : isolate()->factory()->KeyedStoreAndGrowElementMonomorphic_symbol(); 444 : isolate()->factory()->KeyedStoreAndGrowElementMonomorphic_symbol();
443 445
444 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); 446 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_);
445 if (probe->IsCode()) return Handle<Code>::cast(probe); 447 if (probe->IsCode()) return Handle<Code>::cast(probe);
446 448
447 KeyedStoreStubCompiler compiler(isolate(), strict_mode, grow_mode); 449 KeyedStoreStubCompiler compiler(isolate(), strict_mode, grow_mode);
448 Handle<Code> code = compiler.CompileStoreElement(receiver_map); 450 Handle<Code> code = compiler.CompileStoreElement(receiver_map);
449 451
450 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, 0));
451 Map::UpdateCodeCache(receiver_map, name, code); 452 Map::UpdateCodeCache(receiver_map, name, code);
452 return code; 453 return code;
453 } 454 }
454 455
455 456
456 Handle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) { 457 Handle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) {
457 return (strict_mode == kStrictMode) 458 return (strict_mode == kStrictMode)
458 ? isolate_->builtins()->Builtins::StoreIC_Normal_Strict() 459 ? isolate_->builtins()->Builtins::StoreIC_Normal_Strict()
459 : isolate_->builtins()->Builtins::StoreIC_Normal(); 460 : isolate_->builtins()->Builtins::StoreIC_Normal();
460 } 461 }
461 462
462 463
463 Handle<Code> StubCache::ComputeStoreGlobal(Handle<String> name, 464 Handle<Code> StubCache::ComputeStoreGlobal(Handle<String> name,
464 Handle<GlobalObject> receiver, 465 Handle<GlobalObject> receiver,
465 Handle<JSGlobalPropertyCell> cell, 466 Handle<JSGlobalPropertyCell> cell,
466 StrictModeFlag strict_mode) { 467 StrictModeFlag strict_mode) {
467 Code::Flags flags = Code::ComputeMonomorphicFlags( 468 Code::Flags flags = Code::ComputeMonomorphicFlags(
468 Code::STORE_IC, strict_mode); 469 Code::STORE_IC, strict_mode);
469 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 470 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
470 isolate_); 471 isolate_);
471 if (probe->IsCode()) return Handle<Code>::cast(probe); 472 if (probe->IsCode()) return Handle<Code>::cast(probe);
472 473
473 StoreStubCompiler compiler(isolate_, strict_mode); 474 StoreStubCompiler compiler(isolate_, strict_mode);
474 Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name); 475 Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name);
475 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
476 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
477 JSObject::UpdateMapCodeCache(receiver, name, code); 476 JSObject::UpdateMapCodeCache(receiver, name, code);
478 return code; 477 return code;
479 } 478 }
480 479
481 480
482 Handle<Code> StubCache::ComputeStoreCallback( 481 Handle<Code> StubCache::ComputeStoreCallback(
483 Handle<String> name, 482 Handle<String> name,
484 Handle<JSObject> receiver, 483 Handle<JSObject> receiver,
485 Handle<JSObject> holder, 484 Handle<JSObject> holder,
486 Handle<ExecutableAccessorInfo> callback, 485 Handle<ExecutableAccessorInfo> callback,
487 StrictModeFlag strict_mode) { 486 StrictModeFlag strict_mode) {
488 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); 487 ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
489 Code::Flags flags = Code::ComputeMonomorphicFlags( 488 Code::Flags flags = Code::ComputeMonomorphicFlags(
490 Code::STORE_IC, strict_mode, Code::CALLBACKS); 489 Code::STORE_IC, strict_mode, Code::CALLBACKS);
491 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 490 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
492 isolate_); 491 isolate_);
493 if (probe->IsCode()) return Handle<Code>::cast(probe); 492 if (probe->IsCode()) return Handle<Code>::cast(probe);
494 493
495 StoreStubCompiler compiler(isolate_, strict_mode); 494 StoreStubCompiler compiler(isolate_, strict_mode);
496 Handle<Code> code = 495 Handle<Code> code =
497 compiler.CompileStoreCallback(name, receiver, holder, callback); 496 compiler.CompileStoreCallback(name, receiver, holder, callback);
498 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
499 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
500 JSObject::UpdateMapCodeCache(receiver, name, code); 497 JSObject::UpdateMapCodeCache(receiver, name, code);
501 return code; 498 return code;
502 } 499 }
503 500
504 501
505 Handle<Code> StubCache::ComputeStoreViaSetter(Handle<String> name, 502 Handle<Code> StubCache::ComputeStoreViaSetter(Handle<String> name,
506 Handle<JSObject> receiver, 503 Handle<JSObject> receiver,
507 Handle<JSObject> holder, 504 Handle<JSObject> holder,
508 Handle<JSFunction> setter, 505 Handle<JSFunction> setter,
509 StrictModeFlag strict_mode) { 506 StrictModeFlag strict_mode) {
510 Code::Flags flags = Code::ComputeMonomorphicFlags( 507 Code::Flags flags = Code::ComputeMonomorphicFlags(
511 Code::STORE_IC, strict_mode, Code::CALLBACKS); 508 Code::STORE_IC, strict_mode, Code::CALLBACKS);
512 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 509 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
513 isolate_); 510 isolate_);
514 if (probe->IsCode()) return Handle<Code>::cast(probe); 511 if (probe->IsCode()) return Handle<Code>::cast(probe);
515 512
516 StoreStubCompiler compiler(isolate_, strict_mode); 513 StoreStubCompiler compiler(isolate_, strict_mode);
517 Handle<Code> code = 514 Handle<Code> code =
518 compiler.CompileStoreViaSetter(name, receiver, holder, setter); 515 compiler.CompileStoreViaSetter(name, receiver, holder, setter);
519 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
520 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
521 JSObject::UpdateMapCodeCache(receiver, name, code); 516 JSObject::UpdateMapCodeCache(receiver, name, code);
522 return code; 517 return code;
523 } 518 }
524 519
525 520
526 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name, 521 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name,
527 Handle<JSObject> receiver, 522 Handle<JSObject> receiver,
528 StrictModeFlag strict_mode) { 523 StrictModeFlag strict_mode) {
529 Code::Flags flags = Code::ComputeMonomorphicFlags( 524 Code::Flags flags = Code::ComputeMonomorphicFlags(
530 Code::STORE_IC, strict_mode, Code::INTERCEPTOR); 525 Code::STORE_IC, strict_mode, Code::INTERCEPTOR);
531 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 526 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
532 isolate_); 527 isolate_);
533 if (probe->IsCode()) return Handle<Code>::cast(probe); 528 if (probe->IsCode()) return Handle<Code>::cast(probe);
534 529
535 StoreStubCompiler compiler(isolate_, strict_mode); 530 StoreStubCompiler compiler(isolate_, strict_mode);
536 Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name); 531 Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name);
537 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
538 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
539 JSObject::UpdateMapCodeCache(receiver, name, code); 532 JSObject::UpdateMapCodeCache(receiver, name, code);
540 return code; 533 return code;
541 } 534 }
542 535
543 Handle<Code> StubCache::ComputeKeyedStoreField(Handle<String> name, 536 Handle<Code> StubCache::ComputeKeyedStoreField(Handle<String> name,
544 Handle<JSObject> receiver, 537 Handle<JSObject> receiver,
545 int field_index, 538 int field_index,
546 Handle<Map> transition, 539 Handle<Map> transition,
547 StrictModeFlag strict_mode) { 540 StrictModeFlag strict_mode) {
548 Code::StubType type = 541 Code::StubType type =
549 (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION; 542 (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION;
550 Code::Flags flags = Code::ComputeMonomorphicFlags( 543 Code::Flags flags = Code::ComputeMonomorphicFlags(
551 Code::KEYED_STORE_IC, strict_mode, type); 544 Code::KEYED_STORE_IC, strict_mode, type);
552 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 545 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
553 isolate_); 546 isolate_);
554 if (probe->IsCode()) return Handle<Code>::cast(probe); 547 if (probe->IsCode()) return Handle<Code>::cast(probe);
555 548
556 KeyedStoreStubCompiler compiler(isolate(), strict_mode, 549 KeyedStoreStubCompiler compiler(isolate(), strict_mode,
557 DO_NOT_ALLOW_JSARRAY_GROWTH); 550 DO_NOT_ALLOW_JSARRAY_GROWTH);
558 Handle<Code> code = 551 Handle<Code> code =
559 compiler.CompileStoreField(receiver, field_index, transition, name); 552 compiler.CompileStoreField(receiver, field_index, transition, name);
560 PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name));
561 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
562 JSObject::UpdateMapCodeCache(receiver, name, code); 553 JSObject::UpdateMapCodeCache(receiver, name, code);
563 return code; 554 return code;
564 } 555 }
565 556
566 557
567 #define CALL_LOGGER_TAG(kind, type) \ 558 #define CALL_LOGGER_TAG(kind, type) \
568 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) 559 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
569 560
570 Handle<Code> StubCache::ComputeCallConstant(int argc, 561 Handle<Code> StubCache::ComputeCallConstant(int argc,
571 Code::Kind kind, 562 Code::Kind kind,
572 Code::ExtraICState extra_state, 563 Code::ExtraICState extra_state,
573 Handle<String> name, 564 Handle<String> name,
574 Handle<Object> object, 565 Handle<Object> object,
575 Handle<JSObject> holder, 566 Handle<JSObject> holder,
576 Handle<JSFunction> function) { 567 Handle<JSFunction> function) {
577 // Compute the check type and the map. 568 // Compute the check type and the map.
578 InlineCacheHolderFlag cache_holder = 569 InlineCacheHolderFlag cache_holder =
579 IC::GetCodeCacheForObject(*object, *holder); 570 IC::GetCodeCacheForObject(*object, *holder);
580 Handle<JSObject> map_holder( 571 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
581 IC::GetCodeCacheHolder(isolate_, *object, cache_holder)); 572 isolate_, *object, cache_holder));
582 573
583 // Compute check type based on receiver/holder. 574 // Compute check type based on receiver/holder.
584 CheckType check = RECEIVER_MAP_CHECK; 575 CheckType check = RECEIVER_MAP_CHECK;
585 if (object->IsString()) { 576 if (object->IsString()) {
586 check = STRING_CHECK; 577 check = STRING_CHECK;
587 } else if (object->IsNumber()) { 578 } else if (object->IsNumber()) {
588 check = NUMBER_CHECK; 579 check = NUMBER_CHECK;
589 } else if (object->IsBoolean()) { 580 } else if (object->IsBoolean()) {
590 check = BOOLEAN_CHECK; 581 check = BOOLEAN_CHECK;
591 } 582 }
592 583
593 if (check != RECEIVER_MAP_CHECK && 584 if (check != RECEIVER_MAP_CHECK &&
594 !function->IsBuiltin() && 585 !function->IsBuiltin() &&
595 function->shared()->is_classic_mode()) { 586 function->shared()->is_classic_mode()) {
596 // Calling non-strict non-builtins with a value as the receiver 587 // Calling non-strict non-builtins with a value as the receiver
597 // requires boxing. 588 // requires boxing.
598 return Handle<Code>::null(); 589 return Handle<Code>::null();
599 } 590 }
600 591
601 Code::Flags flags = Code::ComputeMonomorphicFlags( 592 Code::Flags flags = Code::ComputeMonomorphicFlags(
602 kind, extra_state, Code::CONSTANT_FUNCTION, argc, cache_holder); 593 kind, extra_state, Code::CONSTANT_FUNCTION, argc, cache_holder);
603 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), 594 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
604 isolate_); 595 isolate_);
605 if (probe->IsCode()) return Handle<Code>::cast(probe); 596 if (probe->IsCode()) return Handle<Code>::cast(probe);
606 597
607 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); 598 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
608 Handle<Code> code = 599 Handle<Code> code =
609 compiler.CompileCallConstant(object, holder, name, check, function); 600 compiler.CompileCallConstant(object, holder, name, check, function);
610 code->set_check_type(check); 601 code->set_check_type(check);
611 ASSERT_EQ(flags, code->flags()); 602 ASSERT_EQ(flags, code->flags());
612 PROFILE(isolate_, 603 PROFILE(isolate_,
613 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 604 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
614 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 605 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
615 JSObject::UpdateMapCodeCache(map_holder, name, code); 606 JSObject::UpdateMapCodeCache(stub_holder, name, code);
616 return code; 607 return code;
617 } 608 }
618 609
619 610
620 Handle<Code> StubCache::ComputeCallField(int argc, 611 Handle<Code> StubCache::ComputeCallField(int argc,
621 Code::Kind kind, 612 Code::Kind kind,
622 Code::ExtraICState extra_state, 613 Code::ExtraICState extra_state,
623 Handle<String> name, 614 Handle<String> name,
624 Handle<Object> object, 615 Handle<Object> object,
625 Handle<JSObject> holder, 616 Handle<JSObject> holder,
626 PropertyIndex index) { 617 PropertyIndex index) {
627 // Compute the check type and the map. 618 // Compute the check type and the map.
628 InlineCacheHolderFlag cache_holder = 619 InlineCacheHolderFlag cache_holder =
629 IC::GetCodeCacheForObject(*object, *holder); 620 IC::GetCodeCacheForObject(*object, *holder);
630 Handle<JSObject> map_holder( 621 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
631 IC::GetCodeCacheHolder(isolate_, *object, cache_holder)); 622 isolate_, *object, cache_holder));
632 623
633 // TODO(1233596): We cannot do receiver map check for non-JS objects 624 // TODO(1233596): We cannot do receiver map check for non-JS objects
634 // because they may be represented as immediates without a 625 // because they may be represented as immediates without a
635 // map. Instead, we check against the map in the holder. 626 // map. Instead, we check against the map in the holder.
636 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 627 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
637 object = holder; 628 object = holder;
638 } 629 }
639 630
640 Code::Flags flags = Code::ComputeMonomorphicFlags( 631 Code::Flags flags = Code::ComputeMonomorphicFlags(
641 kind, extra_state, Code::FIELD, argc, cache_holder); 632 kind, extra_state, Code::FIELD, argc, cache_holder);
642 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), 633 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
643 isolate_); 634 isolate_);
644 if (probe->IsCode()) return Handle<Code>::cast(probe); 635 if (probe->IsCode()) return Handle<Code>::cast(probe);
645 636
646 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); 637 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
647 Handle<Code> code = 638 Handle<Code> code =
648 compiler.CompileCallField(Handle<JSObject>::cast(object), 639 compiler.CompileCallField(Handle<JSObject>::cast(object),
649 holder, index, name); 640 holder, index, name);
650 ASSERT_EQ(flags, code->flags()); 641 ASSERT_EQ(flags, code->flags());
651 PROFILE(isolate_, 642 PROFILE(isolate_,
652 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 643 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
653 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 644 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
654 JSObject::UpdateMapCodeCache(map_holder, name, code); 645 JSObject::UpdateMapCodeCache(stub_holder, name, code);
655 return code; 646 return code;
656 } 647 }
657 648
658 649
659 Handle<Code> StubCache::ComputeCallInterceptor(int argc, 650 Handle<Code> StubCache::ComputeCallInterceptor(int argc,
660 Code::Kind kind, 651 Code::Kind kind,
661 Code::ExtraICState extra_state, 652 Code::ExtraICState extra_state,
662 Handle<String> name, 653 Handle<String> name,
663 Handle<Object> object, 654 Handle<Object> object,
664 Handle<JSObject> holder) { 655 Handle<JSObject> holder) {
665 // Compute the check type and the map. 656 // Compute the check type and the map.
666 InlineCacheHolderFlag cache_holder = 657 InlineCacheHolderFlag cache_holder =
667 IC::GetCodeCacheForObject(*object, *holder); 658 IC::GetCodeCacheForObject(*object, *holder);
668 Handle<JSObject> map_holder( 659 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
669 IC::GetCodeCacheHolder(isolate_, *object, cache_holder)); 660 isolate_, *object, cache_holder));
670 661
671 // TODO(1233596): We cannot do receiver map check for non-JS objects 662 // TODO(1233596): We cannot do receiver map check for non-JS objects
672 // because they may be represented as immediates without a 663 // because they may be represented as immediates without a
673 // map. Instead, we check against the map in the holder. 664 // map. Instead, we check against the map in the holder.
674 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 665 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
675 object = holder; 666 object = holder;
676 } 667 }
677 668
678 Code::Flags flags = Code::ComputeMonomorphicFlags( 669 Code::Flags flags = Code::ComputeMonomorphicFlags(
679 kind, extra_state, Code::INTERCEPTOR, argc, cache_holder); 670 kind, extra_state, Code::INTERCEPTOR, argc, cache_holder);
680 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), 671 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
681 isolate_); 672 isolate_);
682 if (probe->IsCode()) return Handle<Code>::cast(probe); 673 if (probe->IsCode()) return Handle<Code>::cast(probe);
683 674
684 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); 675 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
685 Handle<Code> code = 676 Handle<Code> code =
686 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object), 677 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object),
687 holder, name); 678 holder, name);
688 ASSERT_EQ(flags, code->flags()); 679 ASSERT_EQ(flags, code->flags());
689 PROFILE(isolate(), 680 PROFILE(isolate(),
690 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 681 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
691 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 682 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
692 JSObject::UpdateMapCodeCache(map_holder, name, code); 683 JSObject::UpdateMapCodeCache(stub_holder, name, code);
693 return code; 684 return code;
694 } 685 }
695 686
696 687
697 Handle<Code> StubCache::ComputeCallGlobal(int argc, 688 Handle<Code> StubCache::ComputeCallGlobal(int argc,
698 Code::Kind kind, 689 Code::Kind kind,
699 Code::ExtraICState extra_state, 690 Code::ExtraICState extra_state,
700 Handle<String> name, 691 Handle<String> name,
701 Handle<JSObject> receiver, 692 Handle<JSObject> receiver,
702 Handle<GlobalObject> holder, 693 Handle<GlobalObject> holder,
703 Handle<JSGlobalPropertyCell> cell, 694 Handle<JSGlobalPropertyCell> cell,
704 Handle<JSFunction> function) { 695 Handle<JSFunction> function) {
705 InlineCacheHolderFlag cache_holder = 696 InlineCacheHolderFlag cache_holder =
706 IC::GetCodeCacheForObject(*receiver, *holder); 697 IC::GetCodeCacheForObject(*receiver, *holder);
707 Handle<JSObject> map_holder(IC::GetCodeCacheHolder( 698 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
708 isolate_, *receiver, cache_holder)); 699 isolate_, *receiver, cache_holder));
709 Code::Flags flags = Code::ComputeMonomorphicFlags( 700 Code::Flags flags = Code::ComputeMonomorphicFlags(
710 kind, extra_state, Code::NORMAL, argc, cache_holder); 701 kind, extra_state, Code::NORMAL, argc, cache_holder);
711 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags), 702 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
712 isolate_); 703 isolate_);
713 if (probe->IsCode()) return Handle<Code>::cast(probe); 704 if (probe->IsCode()) return Handle<Code>::cast(probe);
714 705
715 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); 706 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
716 Handle<Code> code = 707 Handle<Code> code =
717 compiler.CompileCallGlobal(receiver, holder, cell, function, name); 708 compiler.CompileCallGlobal(receiver, holder, cell, function, name);
718 ASSERT_EQ(flags, code->flags()); 709 ASSERT_EQ(flags, code->flags());
719 PROFILE(isolate(), 710 PROFILE(isolate(),
720 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 711 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
721 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 712 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
722 JSObject::UpdateMapCodeCache(map_holder, name, code); 713 JSObject::UpdateMapCodeCache(stub_holder, name, code);
723 return code; 714 return code;
724 } 715 }
725 716
726 717
727 static void FillCache(Isolate* isolate, Handle<Code> code) { 718 static void FillCache(Isolate* isolate, Handle<Code> code) {
728 Handle<UnseededNumberDictionary> dictionary = 719 Handle<UnseededNumberDictionary> dictionary =
729 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(), 720 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(),
730 code->flags(), 721 code->flags(),
731 code); 722 code);
732 isolate->heap()->public_set_non_monomorphic_cache(*dictionary); 723 isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 865
875 866
876 Handle<Code> StubCache::ComputeLoadElementPolymorphic( 867 Handle<Code> StubCache::ComputeLoadElementPolymorphic(
877 MapHandleList* receiver_maps) { 868 MapHandleList* receiver_maps) {
878 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); 869 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
879 Handle<PolymorphicCodeCache> cache = 870 Handle<PolymorphicCodeCache> cache =
880 isolate_->factory()->polymorphic_code_cache(); 871 isolate_->factory()->polymorphic_code_cache();
881 Handle<Object> probe = cache->Lookup(receiver_maps, flags); 872 Handle<Object> probe = cache->Lookup(receiver_maps, flags);
882 if (probe->IsCode()) return Handle<Code>::cast(probe); 873 if (probe->IsCode()) return Handle<Code>::cast(probe);
883 874
875 CodeHandleList handlers(receiver_maps->length());
884 KeyedLoadStubCompiler compiler(isolate_); 876 KeyedLoadStubCompiler compiler(isolate_);
885 Handle<Code> code = compiler.CompileLoadElementPolymorphic(receiver_maps); 877 compiler.CompileElementHandlers(receiver_maps, &handlers);
878 Handle<Code> code = compiler.CompilePolymorphicIC(
879 receiver_maps, &handlers, factory()->empty_string(),
880 Code::NORMAL, ELEMENT);
881
882 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
883
886 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 884 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
887 return code; 885 return code;
888 } 886 }
889 887
890 888
889 Handle<Code> StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps,
890 CodeHandleList* handlers,
891 Handle<String> name) {
892 LoadStubCompiler ic_compiler(isolate_);
893 Handle<Code> ic = ic_compiler.CompilePolymorphicIC(
894 receiver_maps, handlers, name, Code::NORMAL, PROPERTY);
895 return ic;
896 }
897
898
891 Handle<Code> StubCache::ComputeStoreElementPolymorphic( 899 Handle<Code> StubCache::ComputeStoreElementPolymorphic(
892 MapHandleList* receiver_maps, 900 MapHandleList* receiver_maps,
893 KeyedAccessGrowMode grow_mode, 901 KeyedAccessGrowMode grow_mode,
894 StrictModeFlag strict_mode) { 902 StrictModeFlag strict_mode) {
895 Handle<PolymorphicCodeCache> cache = 903 Handle<PolymorphicCodeCache> cache =
896 isolate_->factory()->polymorphic_code_cache(); 904 isolate_->factory()->polymorphic_code_cache();
897 Code::ExtraICState extra_state = Code::ComputeExtraICState(grow_mode, 905 Code::ExtraICState extra_state = Code::ComputeExtraICState(grow_mode,
898 strict_mode); 906 strict_mode);
899 Code::Flags flags = 907 Code::Flags flags =
900 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state); 908 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state);
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
1371 holder->LocalLookupRealNamedProperty(*name, lookup); 1379 holder->LocalLookupRealNamedProperty(*name, lookup);
1372 if (lookup->IsFound()) return; 1380 if (lookup->IsFound()) return;
1373 if (holder->GetPrototype()->IsNull()) return; 1381 if (holder->GetPrototype()->IsNull()) return;
1374 holder->GetPrototype()->Lookup(*name, lookup); 1382 holder->GetPrototype()->Lookup(*name, lookup);
1375 } 1383 }
1376 1384
1377 1385
1378 #define __ ACCESS_MASM(masm()) 1386 #define __ ACCESS_MASM(masm())
1379 1387
1380 1388
1381 Register BaseLoadStubCompiler::HandlerFrontendHeader(Handle<JSObject> object, 1389 Register BaseLoadStubCompiler::HandlerFrontendHeader(
1382 Register object_reg, 1390 Handle<JSObject> object,
Jakob Kummerow 2013/03/01 22:21:04 Why the reformatting?
Toon Verwaest 2013/03/04 10:54:08 Done.
1383 Handle<JSObject> holder, 1391 Register object_reg,
1384 Handle<String> name, 1392 Handle<JSObject> holder,
1385 Label* miss, 1393 Handle<String> name,
1386 FrontendCheckType check) { 1394 Label* miss) {
1387 if (check == PERFORM_INITIAL_CHECKS) {
1388 GenerateNameCheck(name, this->name(), miss);
1389 // Check that the receiver isn't a smi.
1390 __ JumpIfSmi(object_reg, miss);
1391 }
1392
1393 // Check the prototype chain. 1395 // Check the prototype chain.
1394 return CheckPrototypes(object, object_reg, holder, 1396 return CheckPrototypes(object, object_reg, holder,
1395 scratch1(), scratch2(), scratch3(), 1397 scratch1(), scratch2(), scratch3(),
1396 name, miss); 1398 name, miss, SKIP_RECEIVER);
1397 } 1399 }
1398 1400
1399 1401
1400 Register BaseLoadStubCompiler::HandlerFrontend(Handle<JSObject> object, 1402 Register BaseLoadStubCompiler::HandlerFrontend(Handle<JSObject> object,
1401 Register object_reg, 1403 Register object_reg,
1402 Handle<JSObject> holder, 1404 Handle<JSObject> holder,
1403 Handle<String> name, 1405 Handle<String> name,
1404 Label* success, 1406 Label* success) {
1405 FrontendCheckType check) {
1406 Label miss; 1407 Label miss;
1407 1408
1408 Register reg = HandlerFrontendHeader( 1409 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
1409 object, object_reg, holder, name, &miss, check);
1410 1410
1411 HandlerFrontendFooter(success, &miss); 1411 HandlerFrontendFooter(success, &miss);
1412 return reg; 1412 return reg;
1413 } 1413 }
1414 1414
1415 1415
1416 Handle<Code> BaseLoadStubCompiler::CompileLoadField(Handle<JSObject> object, 1416 Handle<Code> BaseLoadStubCompiler::CompileLoadField(Handle<JSObject> object,
1417 Handle<JSObject> holder, 1417 Handle<JSObject> holder,
1418 Handle<String> name, 1418 Handle<String> name,
1419 PropertyIndex index) { 1419 PropertyIndex field) {
1420 Label success; 1420 Label miss;
1421 Register reg = HandlerFrontend(object, receiver(), holder, name, 1421
1422 &success, PERFORM_INITIAL_CHECKS); 1422 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss);
1423 __ bind(&success); 1423
1424 GenerateLoadField(reg, holder, index); 1424 LoadFieldStub stub(reg, field.is_inobject(holder), field.translate(holder));
1425 __ jmp(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
1426
1427 __ bind(&miss);
1428 GenerateLoadMiss(masm(), kind());
1425 1429
1426 // Return the generated code. 1430 // Return the generated code.
1427 return GetCode(Code::FIELD, name); 1431 return GetCode(Code::HANDLER_FRAGMENT, Code::FIELD, name);
1428 } 1432 }
1429 1433
1430 1434
1431 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant( 1435 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant(
1432 Handle<JSObject> object, 1436 Handle<JSObject> object,
1433 Handle<JSObject> holder, 1437 Handle<JSObject> holder,
1434 Handle<String> name, 1438 Handle<String> name,
1435 Handle<JSFunction> value) { 1439 Handle<JSFunction> value) {
1436 Label success; 1440 Label success;
1437 HandlerFrontend(object, receiver(), holder, name, 1441 HandlerFrontend(object, receiver(), holder, name, &success);
1438 &success, PERFORM_INITIAL_CHECKS);
1439 __ bind(&success); 1442 __ bind(&success);
1440 GenerateLoadConstant(value); 1443 GenerateLoadConstant(value);
1441 1444
1442 // Return the generated code. 1445 // Return the generated code.
1443 return GetCode(Code::CONSTANT_FUNCTION, name); 1446 return GetCode(Code::HANDLER_FRAGMENT, Code::CONSTANT_FUNCTION, name);
1444 } 1447 }
1445 1448
1446 1449
1447 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback( 1450 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback(
1448 Handle<JSObject> object, 1451 Handle<JSObject> object,
1449 Handle<JSObject> holder, 1452 Handle<JSObject> holder,
1450 Handle<String> name, 1453 Handle<String> name,
1451 Handle<ExecutableAccessorInfo> callback) { 1454 Handle<ExecutableAccessorInfo> callback) {
1452 Label success; 1455 Label success;
1453 1456
1454 Register reg = CallbackHandlerFrontend( 1457 Register reg = CallbackHandlerFrontend(
1455 object, receiver(), holder, name, &success, 1458 object, receiver(), holder, name, &success, callback);
1456 PERFORM_INITIAL_CHECKS, callback);
1457 __ bind(&success); 1459 __ bind(&success);
1458 GenerateLoadCallback(reg, callback); 1460 GenerateLoadCallback(reg, callback);
1459 1461
1460 // Return the generated code. 1462 // Return the generated code.
1461 return GetCode(Code::CALLBACKS, name); 1463 return GetCode(Code::HANDLER_FRAGMENT, Code::CALLBACKS, name);
1462 } 1464 }
1463 1465
1464 1466
1465 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor( 1467 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor(
1466 Handle<JSObject> object, 1468 Handle<JSObject> object,
1467 Handle<JSObject> holder, 1469 Handle<JSObject> holder,
1468 Handle<String> name) { 1470 Handle<String> name) {
1469 Label success; 1471 Label success;
1470 1472
1471 LookupResult lookup(isolate()); 1473 LookupResult lookup(isolate());
1472 LookupPostInterceptor(holder, name, &lookup); 1474 LookupPostInterceptor(holder, name, &lookup);
1473 1475
1474 Register reg = HandlerFrontend(object, receiver(), holder, name, 1476 Register reg = HandlerFrontend(object, receiver(), holder, name, &success);
1475 &success, PERFORM_INITIAL_CHECKS);
1476 __ bind(&success); 1477 __ bind(&success);
1477 // TODO(368): Compile in the whole chain: all the interceptors in 1478 // TODO(368): Compile in the whole chain: all the interceptors in
1478 // prototypes and ultimate answer. 1479 // prototypes and ultimate answer.
1479 GenerateLoadInterceptor(reg, object, holder, &lookup, name); 1480 GenerateLoadInterceptor(reg, object, holder, &lookup, name);
1480 1481
1481 // Return the generated code. 1482 // Return the generated code.
1482 return GetCode(Code::INTERCEPTOR, name); 1483 return GetCode(Code::HANDLER_FRAGMENT, Code::INTERCEPTOR, name);
1483 } 1484 }
1484 1485
1485 1486
1486 void BaseLoadStubCompiler::GenerateLoadPostInterceptor( 1487 void BaseLoadStubCompiler::GenerateLoadPostInterceptor(
1487 Register interceptor_reg, 1488 Register interceptor_reg,
1488 Handle<JSObject> interceptor_holder, 1489 Handle<JSObject> interceptor_holder,
1489 Handle<String> name, 1490 Handle<String> name,
1490 LookupResult* lookup) { 1491 LookupResult* lookup) {
1491 Label success; 1492 Label success;
1492 Handle<JSObject> holder(lookup->holder()); 1493 Handle<JSObject> holder(lookup->holder());
1493 if (lookup->IsField()) { 1494 if (lookup->IsField()) {
1494 // We found FIELD property in prototype chain of interceptor's holder. 1495 PropertyIndex field = lookup->GetFieldIndex();
1495 // Retrieve a field from field's holder. 1496 if (interceptor_holder.is_identical_to(holder)) {
1496 Register reg = HandlerFrontend(interceptor_holder, interceptor_reg, holder, 1497 LoadFieldStub stub(interceptor_reg,
1497 name, &success, SKIP_INITIAL_CHECKS); 1498 field.is_inobject(holder),
1498 __ bind(&success); 1499 field.translate(holder));
1499 GenerateLoadField(reg, holder, lookup->GetFieldIndex()); 1500 __ jmp(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
1501 } else {
1502 // We found FIELD property in prototype chain of interceptor's holder.
1503 // Retrieve a field from field's holder.
1504 Register reg = HandlerFrontend(
1505 interceptor_holder, interceptor_reg, holder, name, &success);
1506 __ bind(&success);
1507 GenerateLoadField(reg, holder, field);
1508 }
1500 } else { 1509 } else {
1501 // We found CALLBACKS property in prototype chain of interceptor's 1510 // We found CALLBACKS property in prototype chain of interceptor's
1502 // holder. 1511 // holder.
1503 ASSERT(lookup->type() == CALLBACKS); 1512 ASSERT(lookup->type() == CALLBACKS);
1504 Handle<ExecutableAccessorInfo> callback( 1513 Handle<ExecutableAccessorInfo> callback(
1505 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 1514 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
1506 ASSERT(callback->getter() != NULL); 1515 ASSERT(callback->getter() != NULL);
1507 1516
1508 Register reg = CallbackHandlerFrontend( 1517 Register reg = CallbackHandlerFrontend(
1509 interceptor_holder, interceptor_reg, holder, 1518 interceptor_holder, interceptor_reg, holder, name, &success, callback);
1510 name, &success, SKIP_INITIAL_CHECKS, callback);
1511 __ bind(&success); 1519 __ bind(&success);
1512 GenerateLoadCallback(reg, callback); 1520 GenerateLoadCallback(reg, callback);
1513 } 1521 }
1514 } 1522 }
1515 1523
1516 1524
1525 Handle<Code> BaseLoadStubCompiler::CompileMonomorphicIC(
1526 Handle<Map> receiver_map,
1527 Handle<Code> handler,
1528 Handle<String> name) {
1529 MapHandleList receiver_maps(1);
1530 receiver_maps.Add(receiver_map);
1531 CodeHandleList handlers(1);
1532 handlers.Add(handler);
1533 Code::StubType type = handler->type();
1534 return CompilePolymorphicIC(&receiver_maps, &handlers, name, type, PROPERTY);
1535 }
1536
1537
1517 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( 1538 Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
1518 Handle<JSObject> object, 1539 Handle<JSObject> object,
1519 Handle<JSObject> holder, 1540 Handle<JSObject> holder,
1520 Handle<String> name, 1541 Handle<String> name,
1521 Handle<JSFunction> getter) { 1542 Handle<JSFunction> getter) {
1522 Label success; 1543 Label success;
1523 HandlerFrontend(object, receiver(), holder, name, 1544 HandlerFrontend(object, receiver(), holder, name, &success);
1524 &success, PERFORM_INITIAL_CHECKS);
1525 1545
1526 __ bind(&success); 1546 __ bind(&success);
1527 GenerateLoadViaGetter(masm(), getter); 1547 GenerateLoadViaGetter(masm(), getter);
1528 1548
1529 // Return the generated code. 1549 // Return the generated code.
1530 return GetCode(Code::CALLBACKS, name); 1550 return GetCode(Code::HANDLER_FRAGMENT, Code::CALLBACKS, name);
1531 } 1551 }
1532 1552
1533 1553
1534 #undef __ 1554 #undef __
1535 1555
1536 1556
1537 Handle<Code> LoadStubCompiler::GetCode(Code::StubType type, 1557 void LoadStubCompiler::JitEvent(Handle<String> name, Handle<Code> code) {
1538 Handle<String> name, 1558 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
1539 InlineCacheState state) { 1559 }
1540 Code::Flags flags = Code::ComputeMonomorphicFlags( 1560
1541 Code::LOAD_IC, Code::kNoExtraICState, type); 1561
1562 void KeyedLoadStubCompiler::JitEvent(Handle<String> name, Handle<Code> code) {
1563 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
1564 }
1565
1566
1567 Handle<Code> BaseLoadStubCompiler::GetCode(Code::IcFragment fragment,
1568 Code::StubType type,
1569 Handle<String> name,
1570 InlineCacheState state) {
1571 Code::Flags flags = Code::ComputeFlags(kind(), state, fragment, type);
1542 Handle<Code> code = GetCodeWithFlags(flags, name); 1572 Handle<Code> code = GetCodeWithFlags(flags, name);
1543 PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 1573 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
1544 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 1574 JitEvent(name, code);
1545 return code; 1575 return code;
1546 } 1576 }
1547 1577
1548 1578
1549 Handle<Code> KeyedLoadStubCompiler::GetCode(Code::StubType type, 1579 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps,
1550 Handle<String> name, 1580 CodeHandleList* handlers) {
1551 InlineCacheState state) {
1552 Code::Flags flags = Code::ComputeFlags(
1553 Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type);
1554 Handle<Code> code = GetCodeWithFlags(flags, name);
1555 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
1556 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
1557 return code;
1558 }
1559
1560
1561 Handle<Code> KeyedLoadStubCompiler::CompileLoadElementPolymorphic(
1562 MapHandleList* receiver_maps) {
1563 CodeHandleList handler_ics(receiver_maps->length());
1564 for (int i = 0; i < receiver_maps->length(); ++i) { 1581 for (int i = 0; i < receiver_maps->length(); ++i) {
1565 Handle<Map> receiver_map = receiver_maps->at(i); 1582 Handle<Map> receiver_map = receiver_maps->at(i);
1566 Handle<Code> cached_stub; 1583 Handle<Code> cached_stub;
1567 1584
1568 if ((receiver_map->instance_type() & kNotStringTag) == 0) { 1585 if ((receiver_map->instance_type() & kNotStringTag) == 0) {
1569 cached_stub = isolate()->builtins()->KeyedLoadIC_String(); 1586 cached_stub = isolate()->builtins()->KeyedLoadIC_String();
1570 } else { 1587 } else {
1571 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 1588 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1572 ElementsKind elements_kind = receiver_map->elements_kind(); 1589 ElementsKind elements_kind = receiver_map->elements_kind();
1573 1590
1574 if (IsFastElementsKind(elements_kind) || 1591 if (IsFastElementsKind(elements_kind) ||
1575 IsExternalArrayElementsKind(elements_kind)) { 1592 IsExternalArrayElementsKind(elements_kind)) {
1576 cached_stub = 1593 cached_stub =
1577 KeyedLoadFastElementStub(is_js_array, 1594 KeyedLoadFastElementStub(is_js_array,
1578 elements_kind).GetCode(isolate()); 1595 elements_kind).GetCode(isolate());
1579 } else { 1596 } else {
1580 ASSERT(elements_kind == DICTIONARY_ELEMENTS); 1597 ASSERT(elements_kind == DICTIONARY_ELEMENTS);
1581 cached_stub = KeyedLoadDictionaryElementStub().GetCode(isolate()); 1598 cached_stub = KeyedLoadDictionaryElementStub().GetCode(isolate());
1582 } 1599 }
1583 } 1600 }
1584 1601
1585 handler_ics.Add(cached_stub); 1602 handlers->Add(cached_stub);
1586 } 1603 }
1587 Handle<Code> code = CompileLoadPolymorphic(receiver_maps, &handler_ics);
1588 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
1589 PROFILE(isolate(),
1590 CodeCreateEvent(Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG, *code, 0));
1591 return code;
1592 } 1604 }
1593 1605
1594 1606
1595
1596 Handle<Code> StoreStubCompiler::GetCode(Code::StubType type, 1607 Handle<Code> StoreStubCompiler::GetCode(Code::StubType type,
1597 Handle<String> name) { 1608 Handle<String> name) {
1598 Code::Flags flags = Code::ComputeMonomorphicFlags( 1609 Code::Flags flags = Code::ComputeMonomorphicFlags(
1599 Code::STORE_IC, strict_mode_, type); 1610 Code::STORE_IC, strict_mode_, type);
1600 Handle<Code> code = GetCodeWithFlags(flags, name); 1611 Handle<Code> code = GetCodeWithFlags(flags, name);
1601 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); 1612 PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
1602 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); 1613 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
1603 return code; 1614 return code;
1604 } 1615 }
1605 1616
1606 1617
1607 Handle<Code> KeyedStoreStubCompiler::GetCode(Code::StubType type, 1618 Handle<Code> KeyedStoreStubCompiler::GetCode(Code::StubType type,
1608 Handle<String> name, 1619 Handle<String> name,
1609 InlineCacheState state) { 1620 InlineCacheState state) {
1610 Code::ExtraICState extra_state = 1621 Code::ExtraICState extra_state =
1611 Code::ComputeExtraICState(grow_mode_, strict_mode_); 1622 Code::ComputeExtraICState(grow_mode_, strict_mode_);
1612 Code::Flags flags = 1623 Code::Flags flags =
1613 Code::ComputeFlags(Code::KEYED_STORE_IC, state, extra_state, type); 1624 Code::ComputeFlags(Code::KEYED_STORE_IC, state, extra_state, type);
1614 Handle<Code> code = GetCodeWithFlags(flags, name); 1625 Handle<Code> code = GetCodeWithFlags(flags, name);
1615 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name)); 1626 PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name));
1616 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); 1627 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
1617 return code; 1628 return code;
1618 } 1629 }
1619 1630
1620 1631
1621 Handle<Code> KeyedStoreStubCompiler::CompileStoreElementPolymorphic( 1632 Handle<Code> KeyedStoreStubCompiler::CompileStoreElementPolymorphic(
1622 MapHandleList* receiver_maps) { 1633 MapHandleList* receiver_maps) {
1623 // Collect MONOMORPHIC stubs for all |receiver_maps|. 1634 // Collect MONOMORPHIC stubs for all |receiver_maps|.
1624 CodeHandleList handler_ics(receiver_maps->length()); 1635 CodeHandleList handlers(receiver_maps->length());
1625 MapHandleList transitioned_maps(receiver_maps->length()); 1636 MapHandleList transitioned_maps(receiver_maps->length());
1626 for (int i = 0; i < receiver_maps->length(); ++i) { 1637 for (int i = 0; i < receiver_maps->length(); ++i) {
1627 Handle<Map> receiver_map(receiver_maps->at(i)); 1638 Handle<Map> receiver_map(receiver_maps->at(i));
1628 Handle<Code> cached_stub; 1639 Handle<Code> cached_stub;
1629 Handle<Map> transitioned_map = 1640 Handle<Map> transitioned_map =
1630 receiver_map->FindTransitionedMap(receiver_maps); 1641 receiver_map->FindTransitionedMap(receiver_maps);
1631 1642
1632 // TODO(mvstanton): The code below is doing pessimistic elements 1643 // TODO(mvstanton): The code below is doing pessimistic elements
1633 // transitions. I would like to stop doing that and rely on Allocation Site 1644 // transitions. I would like to stop doing that and rely on Allocation Site
1634 // Tracking to do a better job of ensuring the data types are what they need 1645 // Tracking to do a better job of ensuring the data types are what they need
1635 // to be. Not all the elements are in place yet, pessimistic elements 1646 // to be. Not all the elements are in place yet, pessimistic elements
1636 // transitions are still important for performance. 1647 // transitions are still important for performance.
1637 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 1648 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1638 ElementsKind elements_kind = receiver_map->elements_kind(); 1649 ElementsKind elements_kind = receiver_map->elements_kind();
1639 if (!transitioned_map.is_null()) { 1650 if (!transitioned_map.is_null()) {
1640 cached_stub = ElementsTransitionAndStoreStub( 1651 cached_stub = ElementsTransitionAndStoreStub(
1641 elements_kind, 1652 elements_kind,
1642 transitioned_map->elements_kind(), 1653 transitioned_map->elements_kind(),
1643 is_js_array, 1654 is_js_array,
1644 strict_mode_, 1655 strict_mode_,
1645 grow_mode_).GetCode(isolate()); 1656 grow_mode_).GetCode(isolate());
1646 } else { 1657 } else {
1647 cached_stub = KeyedStoreElementStub( 1658 cached_stub = KeyedStoreElementStub(
1648 is_js_array, 1659 is_js_array,
1649 elements_kind, 1660 elements_kind,
1650 grow_mode_).GetCode(isolate()); 1661 grow_mode_).GetCode(isolate());
1651 } 1662 }
1652 ASSERT(!cached_stub.is_null()); 1663 ASSERT(!cached_stub.is_null());
1653 handler_ics.Add(cached_stub); 1664 handlers.Add(cached_stub);
1654 transitioned_maps.Add(transitioned_map); 1665 transitioned_maps.Add(transitioned_map);
1655 } 1666 }
1656 Handle<Code> code = 1667 Handle<Code> code =
1657 CompileStorePolymorphic(receiver_maps, &handler_ics, &transitioned_maps); 1668 CompileStorePolymorphic(receiver_maps, &handlers, &transitioned_maps);
1658 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment(); 1669 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
1659 PROFILE(isolate(), 1670 PROFILE(isolate(),
1660 CodeCreateEvent(Logger::KEYED_STORE_POLYMORPHIC_IC_TAG, *code, 0)); 1671 CodeCreateEvent(Logger::KEYED_STORE_POLYMORPHIC_IC_TAG, *code, 0));
1661 return code; 1672 return code;
1662 } 1673 }
1663 1674
1664 1675
1665 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement( 1676 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement(
1666 MacroAssembler* masm) { 1677 MacroAssembler* masm) {
1667 KeyedStoreIC::GenerateSlow(masm); 1678 KeyedStoreIC::GenerateSlow(masm);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1822 Handle<FunctionTemplateInfo>( 1833 Handle<FunctionTemplateInfo>(
1823 FunctionTemplateInfo::cast(signature->receiver())); 1834 FunctionTemplateInfo::cast(signature->receiver()));
1824 } 1835 }
1825 } 1836 }
1826 1837
1827 is_simple_api_call_ = true; 1838 is_simple_api_call_ = true;
1828 } 1839 }
1829 1840
1830 1841
1831 } } // namespace v8::internal 1842 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698