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

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

Issue 110573004: Merge bleeding_edge 17696:18016. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
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
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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
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_map,
104 Code::Kind kind, 104 Code::Kind kind,
105 Code::ExtraICState extra_state) { 105 Code::ExtraICState extra_state,
106 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, extra_state); 106 InlineCacheHolderFlag cache_holder) {
107 Code::Flags flags = Code::ComputeMonomorphicFlags(
108 kind, extra_state, cache_holder);
107 Handle<Object> probe(stub_holder_map->FindInCodeCache(*name, flags), 109 Handle<Object> probe(stub_holder_map->FindInCodeCache(*name, flags),
108 isolate_); 110 isolate_);
109 if (probe->IsCode()) return Handle<Code>::cast(probe); 111 if (probe->IsCode()) return Handle<Code>::cast(probe);
110 return Handle<Code>::null(); 112 return Handle<Code>::null();
111 } 113 }
112 114
113 115
114 Handle<Code> StubCache::FindIC(Handle<Name> name,
115 Handle<JSObject> stub_holder,
116 Code::Kind kind,
117 Code::ExtraICState extra_ic_state) {
118 return FindIC(name, Handle<Map>(stub_holder->map()), kind, extra_ic_state);
119 }
120
121
122 Handle<Code> StubCache::FindHandler(Handle<Name> name, 116 Handle<Code> StubCache::FindHandler(Handle<Name> name,
123 Handle<JSObject> receiver, 117 Handle<HeapObject> stub_holder,
124 Code::Kind kind, 118 Code::Kind kind,
119 InlineCacheHolderFlag cache_holder,
125 StrictModeFlag strict_mode) { 120 StrictModeFlag strict_mode) {
126 Code::ExtraICState extra_ic_state = Code::kNoExtraICState; 121 Code::ExtraICState extra_ic_state = Code::kNoExtraICState;
127 if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) { 122 if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) {
128 extra_ic_state = Code::ComputeExtraICState( 123 extra_ic_state = Code::ComputeExtraICState(
129 STANDARD_STORE, strict_mode); 124 STANDARD_STORE, strict_mode);
130 } 125 }
131 Code::Flags flags = Code::ComputeMonomorphicFlags( 126 Code::Flags flags = Code::ComputeMonomorphicFlags(
132 Code::HANDLER, extra_ic_state, Code::NORMAL, kind); 127 Code::HANDLER, extra_ic_state, cache_holder, Code::NORMAL, kind);
133 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 128
129 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
134 isolate_); 130 isolate_);
135 if (probe->IsCode()) return Handle<Code>::cast(probe); 131 if (probe->IsCode()) return Handle<Code>::cast(probe);
136 return Handle<Code>::null(); 132 return Handle<Code>::null();
137 } 133 }
138 134
139 135
140 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<HeapObject> receiver, 136 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name,
137 Handle<Type> type,
141 Handle<Code> handler, 138 Handle<Code> handler,
142 Handle<Name> name,
143 StrictModeFlag strict_mode) { 139 StrictModeFlag strict_mode) {
144 Code::Kind kind = handler->handler_kind(); 140 Code::Kind kind = handler->handler_kind();
145 Handle<Map> map(receiver->map()); 141 InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type);
146 Handle<Code> ic = FindIC(name, map, kind, strict_mode); 142
147 if (!ic.is_null()) return ic; 143 Handle<Map> stub_holder;
144 Handle<Code> ic;
145 // There are multiple string maps that all use the same prototype. That
146 // prototype cannot hold multiple handlers, one for each of the string maps,
147 // for a single name. Hence, turn off caching of the IC.
148 bool can_be_cached = !type->Is(Type::String());
149 if (can_be_cached) {
150 stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate());
151 ic = FindIC(name, stub_holder, kind, strict_mode, flag);
152 if (!ic.is_null()) return ic;
153 }
148 154
149 if (kind == Code::LOAD_IC) { 155 if (kind == Code::LOAD_IC) {
150 LoadStubCompiler ic_compiler(isolate()); 156 LoadStubCompiler ic_compiler(isolate(), flag);
151 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); 157 ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
152 } else if (kind == Code::KEYED_LOAD_IC) { 158 } else if (kind == Code::KEYED_LOAD_IC) {
153 KeyedLoadStubCompiler ic_compiler(isolate()); 159 KeyedLoadStubCompiler ic_compiler(isolate(), flag);
154 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); 160 ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
155 } else if (kind == Code::STORE_IC) { 161 } else if (kind == Code::STORE_IC) {
156 StoreStubCompiler ic_compiler(isolate(), strict_mode); 162 StoreStubCompiler ic_compiler(isolate(), strict_mode);
157 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); 163 ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
158 } else { 164 } else {
159 ASSERT(kind == Code::KEYED_STORE_IC); 165 ASSERT(kind == Code::KEYED_STORE_IC);
160 KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE); 166 KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE);
161 ic = ic_compiler.CompileMonomorphicIC(map, handler, name); 167 ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
162 } 168 }
163 169
164 HeapObject::UpdateMapCodeCache(receiver, name, ic); 170 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic);
165 return ic; 171 return ic;
166 } 172 }
167 173
168 174
169 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, 175 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
170 Handle<JSObject> receiver) { 176 Handle<Object> object) {
177 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
178 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
179 isolate(), *object, cache_holder));
171 // If no global objects are present in the prototype chain, the load 180 // If no global objects are present in the prototype chain, the load
172 // nonexistent IC stub can be shared for all names for a given map 181 // nonexistent IC stub can be shared for all names for a given map
173 // and we use the empty string for the map cache in that case. If 182 // and we use the empty string for the map cache in that case. If
174 // there are global objects involved, we need to check global 183 // there are global objects involved, we need to check global
175 // property cells in the stub and therefore the stub will be 184 // property cells in the stub and therefore the stub will be
176 // specific to the name. 185 // specific to the name.
177 Handle<Name> cache_name = factory()->empty_string(); 186 Handle<Name> cache_name = factory()->empty_string();
178 Handle<JSObject> current; 187 Handle<JSObject> current;
179 Handle<Object> next = receiver; 188 Handle<Object> next = stub_holder;
180 Handle<JSGlobalObject> global; 189 Handle<JSGlobalObject> global;
181 do { 190 do {
182 current = Handle<JSObject>::cast(next); 191 current = Handle<JSObject>::cast(next);
183 next = Handle<Object>(current->GetPrototype(), isolate_); 192 next = Handle<Object>(current->GetPrototype(), isolate_);
184 if (current->IsJSGlobalObject()) { 193 if (current->IsJSGlobalObject()) {
185 global = Handle<JSGlobalObject>::cast(current); 194 global = Handle<JSGlobalObject>::cast(current);
186 cache_name = name; 195 cache_name = name;
187 } else if (!current->HasFastProperties()) { 196 } else if (!current->HasFastProperties()) {
188 cache_name = name; 197 cache_name = name;
189 } 198 }
190 } while (!next->IsNull()); 199 } while (!next->IsNull());
191 200
192 // Compile the stub that is either shared for all names or 201 // Compile the stub that is either shared for all names or
193 // name specific if there are global objects involved. 202 // name specific if there are global objects involved.
194 Handle<Code> handler = FindHandler(cache_name, receiver, Code::LOAD_IC); 203 Handle<Code> handler = FindHandler(
204 cache_name, stub_holder, Code::LOAD_IC, cache_holder);
195 if (!handler.is_null()) return handler; 205 if (!handler.is_null()) return handler;
196 206
197 LoadStubCompiler compiler(isolate_); 207 LoadStubCompiler compiler(isolate_, cache_holder);
198 handler = 208 handler =
199 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); 209 compiler.CompileLoadNonexistent(object, current, cache_name, global);
200 HeapObject::UpdateMapCodeCache(receiver, cache_name, handler); 210 HeapObject::UpdateMapCodeCache(stub_holder, cache_name, handler);
201 return handler; 211 return handler;
202 } 212 }
203 213
204 214
205 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { 215 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) {
206 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); 216 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
207 Handle<Name> name = 217 Handle<Name> name =
208 isolate()->factory()->KeyedLoadElementMonomorphic_string(); 218 isolate()->factory()->KeyedLoadElementMonomorphic_string();
209 219
210 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); 220 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) 260 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
251 261
252 Handle<Code> StubCache::ComputeCallConstant(int argc, 262 Handle<Code> StubCache::ComputeCallConstant(int argc,
253 Code::Kind kind, 263 Code::Kind kind,
254 Code::ExtraICState extra_state, 264 Code::ExtraICState extra_state,
255 Handle<Name> name, 265 Handle<Name> name,
256 Handle<Object> object, 266 Handle<Object> object,
257 Handle<JSObject> holder, 267 Handle<JSObject> holder,
258 Handle<JSFunction> function) { 268 Handle<JSFunction> function) {
259 // Compute the check type and the map. 269 // Compute the check type and the map.
260 InlineCacheHolderFlag cache_holder = 270 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
261 IC::GetCodeCacheForObject(*object, *holder); 271 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
262 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
263 isolate_, *object, cache_holder)); 272 isolate_, *object, cache_holder));
264 273
265 // Compute check type based on receiver/holder. 274 // Compute check type based on receiver/holder.
266 CheckType check = RECEIVER_MAP_CHECK; 275 CheckType check = RECEIVER_MAP_CHECK;
267 if (object->IsString()) { 276 if (object->IsString()) {
268 check = STRING_CHECK; 277 check = STRING_CHECK;
269 } else if (object->IsSymbol()) { 278 } else if (object->IsSymbol()) {
270 check = SYMBOL_CHECK; 279 check = SYMBOL_CHECK;
271 } else if (object->IsNumber()) { 280 } else if (object->IsNumber()) {
272 check = NUMBER_CHECK; 281 check = NUMBER_CHECK;
273 } else if (object->IsBoolean()) { 282 } else if (object->IsBoolean()) {
274 check = BOOLEAN_CHECK; 283 check = BOOLEAN_CHECK;
275 } 284 }
276 285
277 if (check != RECEIVER_MAP_CHECK && 286 if (check != RECEIVER_MAP_CHECK &&
278 !function->IsBuiltin() && 287 !function->IsBuiltin() &&
279 function->shared()->is_classic_mode()) { 288 function->shared()->is_classic_mode()) {
280 // Calling non-strict non-builtins with a value as the receiver 289 // Calling non-strict non-builtins with a value as the receiver
281 // requires boxing. 290 // requires boxing.
282 return Handle<Code>::null(); 291 return Handle<Code>::null();
283 } 292 }
284 293
285 Code::Flags flags = Code::ComputeMonomorphicFlags( 294 Code::Flags flags = Code::ComputeMonomorphicFlags(
286 kind, extra_state, Code::CONSTANT, argc, cache_holder); 295 kind, extra_state, cache_holder, Code::FAST, argc);
287 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), 296 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
288 isolate_); 297 isolate_);
289 if (probe->IsCode()) return Handle<Code>::cast(probe); 298 if (probe->IsCode()) return Handle<Code>::cast(probe);
290 299
291 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); 300 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
292 Handle<Code> code = 301 Handle<Code> code =
293 compiler.CompileCallConstant(object, holder, name, check, function); 302 compiler.CompileCallConstant(object, holder, name, check, function);
294 code->set_check_type(check); 303 code->set_check_type(check);
295 ASSERT(flags == code->flags()); 304 ASSERT(flags == code->flags());
296 PROFILE(isolate_, 305 PROFILE(isolate_,
297 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 306 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
298 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 307 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
299 308
300 if (CallStubCompiler::CanBeCached(function)) { 309 if (CallStubCompiler::CanBeCached(function)) {
301 HeapObject::UpdateMapCodeCache(stub_holder, name, code); 310 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
302 } 311 }
303 return code; 312 return code;
304 } 313 }
305 314
306 315
307 Handle<Code> StubCache::ComputeCallField(int argc, 316 Handle<Code> StubCache::ComputeCallField(int argc,
308 Code::Kind kind, 317 Code::Kind kind,
309 Code::ExtraICState extra_state, 318 Code::ExtraICState extra_state,
310 Handle<Name> name, 319 Handle<Name> name,
311 Handle<Object> object, 320 Handle<Object> object,
312 Handle<JSObject> holder, 321 Handle<JSObject> holder,
313 PropertyIndex index) { 322 PropertyIndex index) {
314 // Compute the check type and the map. 323 // Compute the check type and the map.
315 InlineCacheHolderFlag cache_holder = 324 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
316 IC::GetCodeCacheForObject(*object, *holder); 325 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
317 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
318 isolate_, *object, cache_holder)); 326 isolate_, *object, cache_holder));
319 327
320 // TODO(1233596): We cannot do receiver map check for non-JS objects 328 // TODO(1233596): We cannot do receiver map check for non-JS objects
321 // because they may be represented as immediates without a 329 // because they may be represented as immediates without a
322 // map. Instead, we check against the map in the holder. 330 // map. Instead, we check against the map in the holder.
323 if (object->IsNumber() || object->IsSymbol() || 331 if (object->IsNumber() || object->IsSymbol() ||
324 object->IsBoolean() || object->IsString()) { 332 object->IsBoolean() || object->IsString()) {
325 object = holder; 333 object = holder;
326 } 334 }
327 335
328 Code::Flags flags = Code::ComputeMonomorphicFlags( 336 Code::Flags flags = Code::ComputeMonomorphicFlags(
329 kind, extra_state, Code::FIELD, argc, cache_holder); 337 kind, extra_state, cache_holder, Code::FAST, argc);
330 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), 338 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
331 isolate_); 339 isolate_);
332 if (probe->IsCode()) return Handle<Code>::cast(probe); 340 if (probe->IsCode()) return Handle<Code>::cast(probe);
333 341
334 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); 342 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
335 Handle<Code> code = 343 Handle<Code> code =
336 compiler.CompileCallField(Handle<JSObject>::cast(object), 344 compiler.CompileCallField(Handle<JSObject>::cast(object),
337 holder, index, name); 345 holder, index, name);
338 ASSERT(flags == code->flags()); 346 ASSERT(flags == code->flags());
339 PROFILE(isolate_, 347 PROFILE(isolate_,
340 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 348 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
341 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 349 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
342 HeapObject::UpdateMapCodeCache(stub_holder, name, code); 350 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
343 return code; 351 return code;
344 } 352 }
345 353
346 354
347 Handle<Code> StubCache::ComputeCallInterceptor(int argc, 355 Handle<Code> StubCache::ComputeCallInterceptor(int argc,
348 Code::Kind kind, 356 Code::Kind kind,
349 Code::ExtraICState extra_state, 357 Code::ExtraICState extra_state,
350 Handle<Name> name, 358 Handle<Name> name,
351 Handle<Object> object, 359 Handle<Object> object,
352 Handle<JSObject> holder) { 360 Handle<JSObject> holder) {
353 // Compute the check type and the map. 361 // Compute the check type and the map.
354 InlineCacheHolderFlag cache_holder = 362 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
355 IC::GetCodeCacheForObject(*object, *holder); 363 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
356 Handle<JSObject> stub_holder(IC::GetCodeCacheHolder(
357 isolate_, *object, cache_holder)); 364 isolate_, *object, cache_holder));
358 365
359 // TODO(1233596): We cannot do receiver map check for non-JS objects 366 // TODO(1233596): We cannot do receiver map check for non-JS objects
360 // because they may be represented as immediates without a 367 // because they may be represented as immediates without a
361 // map. Instead, we check against the map in the holder. 368 // map. Instead, we check against the map in the holder.
362 if (object->IsNumber() || object->IsSymbol() || 369 if (object->IsNumber() || object->IsSymbol() ||
363 object->IsBoolean() || object->IsString()) { 370 object->IsBoolean() || object->IsString()) {
364 object = holder; 371 object = holder;
365 } 372 }
366 373
367 Code::Flags flags = Code::ComputeMonomorphicFlags( 374 Code::Flags flags = Code::ComputeMonomorphicFlags(
368 kind, extra_state, Code::INTERCEPTOR, argc, cache_holder); 375 kind, extra_state, cache_holder, Code::FAST, argc);
369 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), 376 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
370 isolate_); 377 isolate_);
371 if (probe->IsCode()) return Handle<Code>::cast(probe); 378 if (probe->IsCode()) return Handle<Code>::cast(probe);
372 379
373 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); 380 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
374 Handle<Code> code = 381 Handle<Code> code =
375 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object), 382 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object),
376 holder, name); 383 holder, name);
377 ASSERT(flags == code->flags()); 384 ASSERT(flags == code->flags());
378 PROFILE(isolate(), 385 PROFILE(isolate(),
379 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 386 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
380 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 387 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
381 HeapObject::UpdateMapCodeCache(stub_holder, name, code); 388 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
382 return code; 389 return code;
383 } 390 }
384 391
385 392
386 Handle<Code> StubCache::ComputeCallGlobal(int argc, 393 Handle<Code> StubCache::ComputeCallGlobal(int argc,
387 Code::Kind kind, 394 Code::Kind kind,
388 Code::ExtraICState extra_state, 395 Code::ExtraICState extra_state,
389 Handle<Name> name, 396 Handle<Name> name,
390 Handle<JSObject> receiver, 397 Handle<JSObject> receiver,
391 Handle<GlobalObject> holder, 398 Handle<GlobalObject> holder,
392 Handle<PropertyCell> cell, 399 Handle<PropertyCell> cell,
393 Handle<JSFunction> function) { 400 Handle<JSFunction> function) {
394 Code::Flags flags = Code::ComputeMonomorphicFlags( 401 Code::Flags flags = Code::ComputeMonomorphicFlags(
395 kind, extra_state, Code::NORMAL, argc); 402 kind, extra_state, OWN_MAP, Code::NORMAL, argc);
396 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), 403 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
397 isolate_); 404 isolate_);
398 if (probe->IsCode()) return Handle<Code>::cast(probe); 405 if (probe->IsCode()) return Handle<Code>::cast(probe);
399 406
400 CallStubCompiler compiler(isolate(), argc, kind, extra_state); 407 CallStubCompiler compiler(isolate(), argc, kind, extra_state);
401 Handle<Code> code = 408 Handle<Code> code =
402 compiler.CompileCallGlobal(receiver, holder, cell, function, name); 409 compiler.CompileCallGlobal(receiver, holder, cell, function, name);
403 ASSERT(flags == code->flags()); 410 ASSERT(flags == code->flags());
404 PROFILE(isolate(), 411 PROFILE(isolate(),
405 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 412 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 ic->ReplaceNthObject(1, isolate_->heap()->meta_map(), *receiver_map); 580 ic->ReplaceNthObject(1, isolate_->heap()->meta_map(), *receiver_map);
574 581
575 if (!receiver_map->is_shared()) { 582 if (!receiver_map->is_shared()) {
576 Map::UpdateCodeCache(receiver_map, name, ic); 583 Map::UpdateCodeCache(receiver_map, name, ic);
577 } 584 }
578 585
579 return ic; 586 return ic;
580 } 587 }
581 588
582 589
590 // TODO(verwaest): Change this method so it takes in a TypeHandleList.
583 Handle<Code> StubCache::ComputeLoadElementPolymorphic( 591 Handle<Code> StubCache::ComputeLoadElementPolymorphic(
584 MapHandleList* receiver_maps) { 592 MapHandleList* receiver_maps) {
585 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); 593 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
586 Handle<PolymorphicCodeCache> cache = 594 Handle<PolymorphicCodeCache> cache =
587 isolate_->factory()->polymorphic_code_cache(); 595 isolate_->factory()->polymorphic_code_cache();
588 Handle<Object> probe = cache->Lookup(receiver_maps, flags); 596 Handle<Object> probe = cache->Lookup(receiver_maps, flags);
589 if (probe->IsCode()) return Handle<Code>::cast(probe); 597 if (probe->IsCode()) return Handle<Code>::cast(probe);
590 598
599 TypeHandleList types(receiver_maps->length());
600 for (int i = 0; i < receiver_maps->length(); i++) {
601 types.Add(handle(Type::Class(receiver_maps->at(i)), isolate()));
602 }
591 CodeHandleList handlers(receiver_maps->length()); 603 CodeHandleList handlers(receiver_maps->length());
592 KeyedLoadStubCompiler compiler(isolate_); 604 KeyedLoadStubCompiler compiler(isolate_);
593 compiler.CompileElementHandlers(receiver_maps, &handlers); 605 compiler.CompileElementHandlers(receiver_maps, &handlers);
594 Handle<Code> code = compiler.CompilePolymorphicIC( 606 Handle<Code> code = compiler.CompilePolymorphicIC(
595 receiver_maps, &handlers, factory()->empty_string(), 607 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT);
596 Code::NORMAL, ELEMENT);
597 608
598 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); 609 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
599 610
600 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 611 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
601 return code; 612 return code;
602 } 613 }
603 614
604 615
605 Handle<Code> StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps, 616 Handle<Code> StubCache::ComputePolymorphicIC(TypeHandleList* types,
606 CodeHandleList* handlers, 617 CodeHandleList* handlers,
607 int number_of_valid_maps, 618 int number_of_valid_types,
608 Handle<Name> name, 619 Handle<Name> name,
609 StrictModeFlag strict_mode) { 620 StrictModeFlag strict_mode) {
610 Handle<Code> handler = handlers->at(0); 621 Handle<Code> handler = handlers->at(0);
611 Code::Kind kind = handler->handler_kind(); 622 Code::Kind kind = handler->handler_kind();
612 Code::StubType type = number_of_valid_maps == 1 ? handler->type() 623 Code::StubType type = number_of_valid_types == 1 ? handler->type()
613 : Code::NORMAL; 624 : Code::NORMAL;
614 if (kind == Code::LOAD_IC) { 625 if (kind == Code::LOAD_IC) {
615 LoadStubCompiler ic_compiler(isolate_); 626 LoadStubCompiler ic_compiler(isolate_);
616 return ic_compiler.CompilePolymorphicIC( 627 return ic_compiler.CompilePolymorphicIC(
617 receiver_maps, handlers, name, type, PROPERTY); 628 types, handlers, name, type, PROPERTY);
618 } else { 629 } else {
619 ASSERT(kind == Code::STORE_IC); 630 ASSERT(kind == Code::STORE_IC);
620 StoreStubCompiler ic_compiler(isolate_, strict_mode); 631 StoreStubCompiler ic_compiler(isolate_, strict_mode);
621 return ic_compiler.CompilePolymorphicIC( 632 return ic_compiler.CompilePolymorphicIC(
622 receiver_maps, handlers, name, type, PROPERTY); 633 types, handlers, name, type, PROPERTY);
623 } 634 }
624 } 635 }
625 636
626 637
627 Handle<Code> StubCache::ComputeStoreElementPolymorphic( 638 Handle<Code> StubCache::ComputeStoreElementPolymorphic(
628 MapHandleList* receiver_maps, 639 MapHandleList* receiver_maps,
629 KeyedAccessStoreMode store_mode, 640 KeyedAccessStoreMode store_mode,
630 StrictModeFlag strict_mode) { 641 StrictModeFlag strict_mode) {
631 ASSERT(store_mode == STANDARD_STORE || 642 ASSERT(store_mode == STANDARD_STORE ||
632 store_mode == STORE_AND_GROW_NO_TRANSITION || 643 store_mode == STORE_AND_GROW_NO_TRANSITION ||
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 return isolate->heap()->no_interceptor_result_sentinel(); 830 return isolate->heap()->no_interceptor_result_sentinel();
820 } 831 }
821 832
822 833
823 static MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) { 834 static MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) {
824 // If the load is non-contextual, just return the undefined result. 835 // If the load is non-contextual, just return the undefined result.
825 // Note that both keyed and non-keyed loads may end up here, so we 836 // Note that both keyed and non-keyed loads may end up here, so we
826 // can't use either LoadIC or KeyedLoadIC constructors. 837 // can't use either LoadIC or KeyedLoadIC constructors.
827 HandleScope scope(isolate); 838 HandleScope scope(isolate);
828 IC ic(IC::NO_EXTRA_FRAME, isolate); 839 IC ic(IC::NO_EXTRA_FRAME, isolate);
829 ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub()); 840 ASSERT(ic.IsLoadStub());
830 if (!ic.SlowIsUndeclaredGlobal()) return isolate->heap()->undefined_value(); 841 if (!ic.SlowIsUndeclaredGlobal()) return isolate->heap()->undefined_value();
831 842
832 // Throw a reference error. 843 // Throw a reference error.
833 Handle<Name> name_handle(name); 844 Handle<Name> name_handle(name);
834 Handle<Object> error = 845 Handle<Object> error =
835 isolate->factory()->NewReferenceError("not_defined", 846 isolate->factory()->NewReferenceError("not_defined",
836 HandleVector(&name_handle, 1)); 847 HandleVector(&name_handle, 1));
837 return isolate->Throw(*error); 848 return isolate->Throw(*error);
838 } 849 }
839 850
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 #undef CALL_LOGGER_TAG 1100 #undef CALL_LOGGER_TAG
1090 1101
1091 1102
1092 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, 1103 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
1093 const char* name) { 1104 const char* name) {
1094 // Create code object in the heap. 1105 // Create code object in the heap.
1095 CodeDesc desc; 1106 CodeDesc desc;
1096 masm_.GetCode(&desc); 1107 masm_.GetCode(&desc);
1097 Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject()); 1108 Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject());
1098 #ifdef ENABLE_DISASSEMBLER 1109 #ifdef ENABLE_DISASSEMBLER
1099 if (FLAG_print_code_stubs) { 1110 if (FLAG_print_code_stubs) code->Disassemble(name);
1100 CodeTracer::Scope trace_scope(isolate()->GetCodeTracer());
1101 code->Disassemble(name, trace_scope.file());
1102 }
1103 #endif 1111 #endif
1104 return code; 1112 return code;
1105 } 1113 }
1106 1114
1107 1115
1108 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, 1116 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
1109 Handle<Name> name) { 1117 Handle<Name> name) {
1110 return (FLAG_print_code_stubs && !name.is_null() && name->IsString()) 1118 return (FLAG_print_code_stubs && !name.is_null() && name->IsString())
1111 ? GetCodeWithFlags(flags, *Handle<String>::cast(name)->ToCString()) 1119 ? GetCodeWithFlags(flags, *Handle<String>::cast(name)->ToCString())
1112 : GetCodeWithFlags(flags, NULL); 1120 : GetCodeWithFlags(flags, NULL);
1113 } 1121 }
1114 1122
1115 1123
1116 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder, 1124 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder,
1117 Handle<Name> name, 1125 Handle<Name> name,
1118 LookupResult* lookup) { 1126 LookupResult* lookup) {
1119 holder->LocalLookupRealNamedProperty(*name, lookup); 1127 holder->LocalLookupRealNamedProperty(*name, lookup);
1120 if (lookup->IsFound()) return; 1128 if (lookup->IsFound()) return;
1121 if (holder->GetPrototype()->IsNull()) return; 1129 if (holder->GetPrototype()->IsNull()) return;
1122 holder->GetPrototype()->Lookup(*name, lookup); 1130 holder->GetPrototype()->Lookup(*name, lookup);
1123 } 1131 }
1124 1132
1125 1133
1126 #define __ ACCESS_MASM(masm()) 1134 #define __ ACCESS_MASM(masm())
1127 1135
1128 1136
1129 Register LoadStubCompiler::HandlerFrontendHeader( 1137 Register LoadStubCompiler::HandlerFrontendHeader(
1130 Handle<JSObject> object, 1138 Handle<Object> object,
1131 Register object_reg, 1139 Register object_reg,
1132 Handle<JSObject> holder, 1140 Handle<JSObject> holder,
1133 Handle<Name> name, 1141 Handle<Name> name,
1134 Label* miss) { 1142 Label* miss) {
1135 return CheckPrototypes(object, object_reg, holder, 1143 Handle<JSObject> receiver;
1144 PrototypeCheckType check_type = CHECK_ALL_MAPS;
1145 int function_index = -1;
1146 if (object->IsJSObject()) {
1147 receiver = Handle<JSObject>::cast(object);
1148 check_type = SKIP_RECEIVER;
1149 } else {
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
1164 GenerateDirectLoadGlobalFunctionPrototype(
1165 masm(), function_index, scratch1(), miss);
1166 receiver = handle(JSObject::cast(object->GetPrototype(isolate())));
1167 object_reg = scratch1();
1168 }
1169
1170 // Check that the maps starting from the prototype haven't changed.
1171 return CheckPrototypes(receiver, object_reg, holder,
1136 scratch1(), scratch2(), scratch3(), 1172 scratch1(), scratch2(), scratch3(),
1137 name, miss, SKIP_RECEIVER); 1173 name, miss, check_type);
1138 } 1174 }
1139 1175
1140 1176
1141 // HandlerFrontend for store uses the name register. It has to be restored 1177 // HandlerFrontend for store uses the name register. It has to be restored
1142 // before a miss. 1178 // before a miss.
1143 Register StoreStubCompiler::HandlerFrontendHeader( 1179 Register StoreStubCompiler::HandlerFrontendHeader(
1144 Handle<JSObject> object, 1180 Handle<Object> object,
1145 Register object_reg, 1181 Register object_reg,
1146 Handle<JSObject> holder, 1182 Handle<JSObject> holder,
1147 Handle<Name> name, 1183 Handle<Name> name,
1148 Label* miss) { 1184 Label* miss) {
1149 return CheckPrototypes(object, object_reg, holder, 1185 return CheckPrototypes(Handle<JSObject>::cast(object), object_reg, holder,
1150 this->name(), scratch1(), scratch2(), 1186 this->name(), scratch1(), scratch2(),
1151 name, miss, SKIP_RECEIVER); 1187 name, miss, SKIP_RECEIVER);
1152 } 1188 }
1153 1189
1154 1190
1155 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<JSObject> object, 1191 bool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) {
1192 for (int i = 0; i < types->length(); ++i) {
1193 if (types->at(i)->Is(Type::Number())) return true;
1194 }
1195 return false;
1196 }
1197
1198
1199 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Object> object,
1156 Register object_reg, 1200 Register object_reg,
1157 Handle<JSObject> holder, 1201 Handle<JSObject> holder,
1158 Handle<Name> name, 1202 Handle<Name> name) {
1159 Label* success) {
1160 Label miss; 1203 Label miss;
1161 1204
1162 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1205 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
1163 1206
1164 HandlerFrontendFooter(name, success, &miss); 1207 HandlerFrontendFooter(name, &miss);
1208
1165 return reg; 1209 return reg;
1166 } 1210 }
1167 1211
1168 1212
1169 void LoadStubCompiler::NonexistentHandlerFrontend( 1213 void LoadStubCompiler::NonexistentHandlerFrontend(
1170 Handle<JSObject> object, 1214 Handle<Object> object,
1171 Handle<JSObject> last, 1215 Handle<JSObject> last,
1172 Handle<Name> name, 1216 Handle<Name> name,
1173 Label* success,
1174 Handle<JSGlobalObject> global) { 1217 Handle<JSGlobalObject> global) {
1175 Label miss; 1218 Label miss;
1176 1219
1177 Register holder = 1220 Register holder = HandlerFrontendHeader(
1178 HandlerFrontendHeader(object, receiver(), last, name, &miss); 1221 object, receiver(), last, name, &miss);
1179 1222
1180 if (!last->HasFastProperties() && 1223 if (!last->HasFastProperties() &&
1181 !last->IsJSGlobalObject() && 1224 !last->IsJSGlobalObject() &&
1182 !last->IsJSGlobalProxy()) { 1225 !last->IsJSGlobalProxy()) {
1183 if (!name->IsUniqueName()) { 1226 if (!name->IsUniqueName()) {
1184 ASSERT(name->IsString()); 1227 ASSERT(name->IsString());
1185 name = factory()->InternalizeString(Handle<String>::cast(name)); 1228 name = factory()->InternalizeString(Handle<String>::cast(name));
1186 } 1229 }
1187 ASSERT(last->property_dictionary()->FindEntry(*name) == 1230 ASSERT(last->property_dictionary()->FindEntry(*name) ==
1188 NameDictionary::kNotFound); 1231 NameDictionary::kNotFound);
1189 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name, 1232 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name,
1190 scratch2(), scratch3()); 1233 scratch2(), scratch3());
1191 } 1234 }
1192 1235
1193 // If the last object in the prototype chain is a global object, 1236 // If the last object in the prototype chain is a global object,
1194 // check that the global property cell is empty. 1237 // check that the global property cell is empty.
1195 if (!global.is_null()) { 1238 if (!global.is_null()) {
1196 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); 1239 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1197 } 1240 }
1198 1241
1199 HandlerFrontendFooter(name, success, &miss); 1242 HandlerFrontendFooter(name, &miss);
1200 } 1243 }
1201 1244
1202 1245
1203 Handle<Code> LoadStubCompiler::CompileLoadField( 1246 Handle<Code> LoadStubCompiler::CompileLoadField(
1204 Handle<JSObject> object, 1247 Handle<Object> object,
1205 Handle<JSObject> holder, 1248 Handle<JSObject> holder,
1206 Handle<Name> name, 1249 Handle<Name> name,
1207 PropertyIndex field, 1250 PropertyIndex field,
1208 Representation representation) { 1251 Representation representation) {
1209 Label miss; 1252 Label miss;
1210 1253
1211 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); 1254 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss);
1212 1255
1213 GenerateLoadField(reg, holder, field, representation); 1256 GenerateLoadField(reg, holder, field, representation);
1214 1257
1215 __ bind(&miss); 1258 __ bind(&miss);
1216 TailCallBuiltin(masm(), MissBuiltin(kind())); 1259 TailCallBuiltin(masm(), MissBuiltin(kind()));
1217 1260
1218 // Return the generated code. 1261 // Return the generated code.
1219 return GetCode(kind(), Code::FIELD, name); 1262 return GetCode(kind(), Code::FAST, name);
1220 } 1263 }
1221 1264
1222 1265
1223 Handle<Code> LoadStubCompiler::CompileLoadConstant( 1266 Handle<Code> LoadStubCompiler::CompileLoadConstant(
1224 Handle<JSObject> object, 1267 Handle<Object> object,
1225 Handle<JSObject> holder, 1268 Handle<JSObject> holder,
1226 Handle<Name> name, 1269 Handle<Name> name,
1227 Handle<Object> value) { 1270 Handle<Object> value) {
1228 Label success; 1271 HandlerFrontend(object, receiver(), holder, name);
1229 HandlerFrontend(object, receiver(), holder, name, &success);
1230 __ bind(&success);
1231 GenerateLoadConstant(value); 1272 GenerateLoadConstant(value);
1232 1273
1233 // Return the generated code. 1274 // Return the generated code.
1234 return GetCode(kind(), Code::CONSTANT, name); 1275 return GetCode(kind(), Code::FAST, name);
1235 } 1276 }
1236 1277
1237 1278
1238 Handle<Code> LoadStubCompiler::CompileLoadCallback( 1279 Handle<Code> LoadStubCompiler::CompileLoadCallback(
1239 Handle<JSObject> object, 1280 Handle<Object> object,
1240 Handle<JSObject> holder, 1281 Handle<JSObject> holder,
1241 Handle<Name> name, 1282 Handle<Name> name,
1242 Handle<ExecutableAccessorInfo> callback) { 1283 Handle<ExecutableAccessorInfo> callback) {
1243 Label success;
1244
1245 Register reg = CallbackHandlerFrontend( 1284 Register reg = CallbackHandlerFrontend(
1246 object, receiver(), holder, name, &success, callback); 1285 object, receiver(), holder, name, callback);
1247 __ bind(&success);
1248 GenerateLoadCallback(reg, callback); 1286 GenerateLoadCallback(reg, callback);
1249 1287
1250 // Return the generated code. 1288 // Return the generated code.
1251 return GetCode(kind(), Code::CALLBACKS, name); 1289 return GetCode(kind(), Code::FAST, name);
1252 } 1290 }
1253 1291
1254 1292
1255 Handle<Code> LoadStubCompiler::CompileLoadCallback( 1293 Handle<Code> LoadStubCompiler::CompileLoadCallback(
1256 Handle<JSObject> object, 1294 Handle<Object> object,
1257 Handle<JSObject> holder, 1295 Handle<JSObject> holder,
1258 Handle<Name> name, 1296 Handle<Name> name,
1259 const CallOptimization& call_optimization) { 1297 const CallOptimization& call_optimization) {
1260 ASSERT(call_optimization.is_simple_api_call()); 1298 ASSERT(call_optimization.is_simple_api_call());
1261 Label success;
1262
1263 Handle<JSFunction> callback = call_optimization.constant_function(); 1299 Handle<JSFunction> callback = call_optimization.constant_function();
1264 CallbackHandlerFrontend( 1300 CallbackHandlerFrontend(object, receiver(), holder, name, callback);
1265 object, receiver(), holder, name, &success, callback);
1266 __ bind(&success);
1267 GenerateLoadCallback(call_optimization); 1301 GenerateLoadCallback(call_optimization);
1268 1302
1269 // Return the generated code. 1303 // Return the generated code.
1270 return GetCode(kind(), Code::CALLBACKS, name); 1304 return GetCode(kind(), Code::FAST, name);
1271 } 1305 }
1272 1306
1273 1307
1274 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( 1308 Handle<Code> LoadStubCompiler::CompileLoadInterceptor(
1275 Handle<JSObject> object, 1309 Handle<Object> object,
1276 Handle<JSObject> holder, 1310 Handle<JSObject> holder,
1277 Handle<Name> name) { 1311 Handle<Name> name) {
1278 Label success;
1279
1280 LookupResult lookup(isolate()); 1312 LookupResult lookup(isolate());
1281 LookupPostInterceptor(holder, name, &lookup); 1313 LookupPostInterceptor(holder, name, &lookup);
1282 1314
1283 Register reg = HandlerFrontend(object, receiver(), holder, name, &success); 1315 Register reg = HandlerFrontend(object, receiver(), holder, name);
1284 __ bind(&success);
1285 // TODO(368): Compile in the whole chain: all the interceptors in 1316 // TODO(368): Compile in the whole chain: all the interceptors in
1286 // prototypes and ultimate answer. 1317 // prototypes and ultimate answer.
1287 GenerateLoadInterceptor(reg, object, holder, &lookup, name); 1318 GenerateLoadInterceptor(reg, object, holder, &lookup, name);
1288 1319
1289 // Return the generated code. 1320 // Return the generated code.
1290 return GetCode(kind(), Code::INTERCEPTOR, name); 1321 return GetCode(kind(), Code::FAST, name);
1291 } 1322 }
1292 1323
1293 1324
1294 void LoadStubCompiler::GenerateLoadPostInterceptor( 1325 void LoadStubCompiler::GenerateLoadPostInterceptor(
1295 Register interceptor_reg, 1326 Register interceptor_reg,
1296 Handle<JSObject> interceptor_holder, 1327 Handle<JSObject> interceptor_holder,
1297 Handle<Name> name, 1328 Handle<Name> name,
1298 LookupResult* lookup) { 1329 LookupResult* lookup) {
1299 Label success;
1300 Handle<JSObject> holder(lookup->holder()); 1330 Handle<JSObject> holder(lookup->holder());
1301 if (lookup->IsField()) { 1331 if (lookup->IsField()) {
1302 PropertyIndex field = lookup->GetFieldIndex(); 1332 PropertyIndex field = lookup->GetFieldIndex();
1303 if (interceptor_holder.is_identical_to(holder)) { 1333 if (interceptor_holder.is_identical_to(holder)) {
1304 GenerateLoadField( 1334 GenerateLoadField(
1305 interceptor_reg, holder, field, lookup->representation()); 1335 interceptor_reg, holder, field, lookup->representation());
1306 } else { 1336 } else {
1307 // We found FIELD property in prototype chain of interceptor's holder. 1337 // We found FIELD property in prototype chain of interceptor's holder.
1308 // Retrieve a field from field's holder. 1338 // Retrieve a field from field's holder.
1309 Register reg = HandlerFrontend( 1339 Register reg = HandlerFrontend(
1310 interceptor_holder, interceptor_reg, holder, name, &success); 1340 interceptor_holder, interceptor_reg, holder, name);
1311 __ bind(&success);
1312 GenerateLoadField( 1341 GenerateLoadField(
1313 reg, holder, field, lookup->representation()); 1342 reg, holder, field, lookup->representation());
1314 } 1343 }
1315 } else { 1344 } else {
1316 // We found CALLBACKS property in prototype chain of interceptor's 1345 // We found CALLBACKS property in prototype chain of interceptor's
1317 // holder. 1346 // holder.
1318 ASSERT(lookup->type() == CALLBACKS); 1347 ASSERT(lookup->type() == CALLBACKS);
1319 Handle<ExecutableAccessorInfo> callback( 1348 Handle<ExecutableAccessorInfo> callback(
1320 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); 1349 ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
1321 ASSERT(callback->getter() != NULL); 1350 ASSERT(callback->getter() != NULL);
1322 1351
1323 Register reg = CallbackHandlerFrontend( 1352 Register reg = CallbackHandlerFrontend(
1324 interceptor_holder, interceptor_reg, holder, name, &success, callback); 1353 interceptor_holder, interceptor_reg, holder, name, callback);
1325 __ bind(&success);
1326 GenerateLoadCallback(reg, callback); 1354 GenerateLoadCallback(reg, callback);
1327 } 1355 }
1328 } 1356 }
1329 1357
1330 1358
1331 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC( 1359 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC(
1332 Handle<Map> receiver_map, 1360 Handle<Type> type,
1333 Handle<Code> handler, 1361 Handle<Code> handler,
1334 Handle<Name> name) { 1362 Handle<Name> name) {
1335 MapHandleList receiver_maps(1); 1363 TypeHandleList types(1);
1336 receiver_maps.Add(receiver_map);
1337 CodeHandleList handlers(1); 1364 CodeHandleList handlers(1);
1365 types.Add(type);
1338 handlers.Add(handler); 1366 handlers.Add(handler);
1339 Code::StubType type = handler->type(); 1367 Code::StubType stub_type = handler->type();
1340 return CompilePolymorphicIC(&receiver_maps, &handlers, name, type, PROPERTY); 1368 return CompilePolymorphicIC(&types, &handlers, name, stub_type, PROPERTY);
1341 } 1369 }
1342 1370
1343 1371
1344 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( 1372 Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
1345 Handle<JSObject> object, 1373 Handle<Object> object,
1346 Handle<JSObject> holder, 1374 Handle<JSObject> holder,
1347 Handle<Name> name, 1375 Handle<Name> name,
1348 Handle<JSFunction> getter) { 1376 Handle<JSFunction> getter) {
1349 Label success; 1377 HandlerFrontend(object, receiver(), holder, name);
1350 HandlerFrontend(object, receiver(), holder, name, &success);
1351
1352 __ bind(&success);
1353 GenerateLoadViaGetter(masm(), receiver(), getter); 1378 GenerateLoadViaGetter(masm(), receiver(), getter);
1354 1379
1355 // Return the generated code. 1380 // Return the generated code.
1356 return GetCode(kind(), Code::CALLBACKS, name); 1381 return GetCode(kind(), Code::FAST, name);
1357 } 1382 }
1358 1383
1359 1384
1360 Handle<Code> StoreStubCompiler::CompileStoreTransition( 1385 Handle<Code> StoreStubCompiler::CompileStoreTransition(
1361 Handle<JSObject> object, 1386 Handle<JSObject> object,
1362 LookupResult* lookup, 1387 LookupResult* lookup,
1363 Handle<Map> transition, 1388 Handle<Map> transition,
1364 Handle<Name> name) { 1389 Handle<Name> name) {
1365 Label miss, slow; 1390 Label miss, slow;
1366 1391
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1403 &slow); 1428 &slow);
1404 1429
1405 // Handle store cache miss. 1430 // Handle store cache miss.
1406 GenerateRestoreName(masm(), &miss, name); 1431 GenerateRestoreName(masm(), &miss, name);
1407 TailCallBuiltin(masm(), MissBuiltin(kind())); 1432 TailCallBuiltin(masm(), MissBuiltin(kind()));
1408 1433
1409 GenerateRestoreName(masm(), &slow, name); 1434 GenerateRestoreName(masm(), &slow, name);
1410 TailCallBuiltin(masm(), SlowBuiltin(kind())); 1435 TailCallBuiltin(masm(), SlowBuiltin(kind()));
1411 1436
1412 // Return the generated code. 1437 // Return the generated code.
1413 return GetCode(kind(), Code::TRANSITION, name); 1438 return GetCode(kind(), Code::FAST, name);
1414 } 1439 }
1415 1440
1416 1441
1417 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, 1442 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
1418 LookupResult* lookup, 1443 LookupResult* lookup,
1419 Handle<Name> name) { 1444 Handle<Name> name) {
1420 Label miss; 1445 Label miss;
1421 1446
1422 HandlerFrontendHeader(object, receiver(), object, name, &miss); 1447 HandlerFrontendHeader(object, receiver(), object, name, &miss);
1423 1448
1424 // Generate store field code. 1449 // Generate store field code.
1425 GenerateStoreField(masm(), 1450 GenerateStoreField(masm(),
1426 object, 1451 object,
1427 lookup, 1452 lookup,
1428 receiver(), this->name(), value(), scratch1(), scratch2(), 1453 receiver(), this->name(), value(), scratch1(), scratch2(),
1429 &miss); 1454 &miss);
1430 1455
1431 // Handle store cache miss. 1456 // Handle store cache miss.
1432 __ bind(&miss); 1457 __ bind(&miss);
1433 TailCallBuiltin(masm(), MissBuiltin(kind())); 1458 TailCallBuiltin(masm(), MissBuiltin(kind()));
1434 1459
1435 // Return the generated code. 1460 // Return the generated code.
1436 return GetCode(kind(), Code::FIELD, name); 1461 return GetCode(kind(), Code::FAST, name);
1437 } 1462 }
1438 1463
1439 1464
1440 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( 1465 Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
1441 Handle<JSObject> object, 1466 Handle<JSObject> object,
1442 Handle<JSObject> holder, 1467 Handle<JSObject> holder,
1443 Handle<Name> name, 1468 Handle<Name> name,
1444 Handle<JSFunction> setter) { 1469 Handle<JSFunction> setter) {
1445 Label success; 1470 HandlerFrontend(object, receiver(), holder, name);
1446 HandlerFrontend(object, receiver(), holder, name, &success);
1447
1448 __ bind(&success);
1449 GenerateStoreViaSetter(masm(), setter); 1471 GenerateStoreViaSetter(masm(), setter);
1450 1472
1451 return GetCode(kind(), Code::CALLBACKS, name); 1473 return GetCode(kind(), Code::FAST, name);
1452 } 1474 }
1453 1475
1454 1476
1455 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( 1477 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
1456 Handle<Map> receiver_map) { 1478 Handle<Map> receiver_map) {
1457 ElementsKind elements_kind = receiver_map->elements_kind(); 1479 ElementsKind elements_kind = receiver_map->elements_kind();
1458 if (receiver_map->has_fast_elements() || 1480 if (receiver_map->has_fast_elements() ||
1459 receiver_map->has_external_array_elements()) { 1481 receiver_map->has_external_array_elements()) {
1460 Handle<Code> stub = KeyedLoadFastElementStub( 1482 Handle<Code> stub = KeyedLoadFastElementStub(
1461 receiver_map->instance_type() == JS_ARRAY_TYPE, 1483 receiver_map->instance_type() == JS_ARRAY_TYPE,
1462 elements_kind).GetCode(isolate()); 1484 elements_kind).GetCode(isolate());
1463 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); 1485 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
1464 } else { 1486 } else {
1465 Handle<Code> stub = 1487 Handle<Code> stub = FLAG_compiled_keyed_dictionary_loads
1466 KeyedLoadDictionaryElementStub().GetCode(isolate()); 1488 ? KeyedLoadDictionaryElementStub().GetCode(isolate())
1489 : KeyedLoadDictionaryElementPlatformStub().GetCode(isolate());
1467 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); 1490 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
1468 } 1491 }
1469 1492
1470 TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss); 1493 TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss);
1471 1494
1472 // Return the generated code. 1495 // Return the generated code.
1473 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); 1496 return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
1474 } 1497 }
1475 1498
1476 1499
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1548 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); 1571 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
1549 JitEvent(name, code); 1572 JitEvent(name, code);
1550 return code; 1573 return code;
1551 } 1574 }
1552 1575
1553 1576
1554 Handle<Code> BaseLoadStoreStubCompiler::GetCode(Code::Kind kind, 1577 Handle<Code> BaseLoadStoreStubCompiler::GetCode(Code::Kind kind,
1555 Code::StubType type, 1578 Code::StubType type,
1556 Handle<Name> name) { 1579 Handle<Name> name) {
1557 Code::Flags flags = Code::ComputeFlags( 1580 Code::Flags flags = Code::ComputeFlags(
1558 Code::HANDLER, MONOMORPHIC, extra_state(), type, kind); 1581 Code::HANDLER, MONOMORPHIC, extra_state(), type, kind, cache_holder_);
1559 Handle<Code> code = GetCodeWithFlags(flags, name); 1582 Handle<Code> code = GetCodeWithFlags(flags, name);
1560 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); 1583 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
1561 JitEvent(name, code); 1584 JitEvent(name, code);
1562 return code; 1585 return code;
1563 } 1586 }
1564 1587
1565 1588
1566 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps, 1589 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps,
1567 CodeHandleList* handlers) { 1590 CodeHandleList* handlers) {
1568 for (int i = 0; i < receiver_maps->length(); ++i) { 1591 for (int i = 0; i < receiver_maps->length(); ++i) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1716 holder, 1739 holder,
1717 cell, 1740 cell,
1718 function, 1741 function,
1719 fname); 1742 fname);
1720 } 1743 }
1721 1744
1722 1745
1723 Handle<Code> CallStubCompiler::GetCode(Code::StubType type, 1746 Handle<Code> CallStubCompiler::GetCode(Code::StubType type,
1724 Handle<Name> name) { 1747 Handle<Name> name) {
1725 int argc = arguments_.immediate(); 1748 int argc = arguments_.immediate();
1726 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, 1749 Code::Flags flags = Code::ComputeMonomorphicFlags(
1727 extra_state_, 1750 kind_, extra_state_, cache_holder_, type, argc);
1728 type,
1729 argc,
1730 cache_holder_);
1731 return GetCodeWithFlags(flags, name); 1751 return GetCodeWithFlags(flags, name);
1732 } 1752 }
1733 1753
1734 1754
1735 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) { 1755 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) {
1736 Handle<String> function_name; 1756 Handle<String> function_name;
1737 if (function->shared()->name()->IsString()) { 1757 if (function->shared()->name()->IsString()) {
1738 function_name = Handle<String>(String::cast(function->shared()->name())); 1758 function_name = Handle<String>(String::cast(function->shared()->name()));
1739 } 1759 }
1740 return GetCode(Code::CONSTANT, function_name); 1760 return GetCode(Code::FAST, function_name);
1741 } 1761 }
1742 1762
1743 1763
1744 CallOptimization::CallOptimization(LookupResult* lookup) { 1764 CallOptimization::CallOptimization(LookupResult* lookup) {
1745 if (lookup->IsFound() && 1765 if (lookup->IsFound() &&
1746 lookup->IsCacheable() && 1766 lookup->IsCacheable() &&
1747 lookup->IsConstantFunction()) { 1767 lookup->IsConstantFunction()) {
1748 // We only optimize constant function calls. 1768 // We only optimize constant function calls.
1749 Initialize(Handle<JSFunction>(lookup->GetConstantFunction())); 1769 Initialize(Handle<JSFunction>(lookup->GetConstantFunction()));
1750 } else { 1770 } else {
1751 Initialize(Handle<JSFunction>::null()); 1771 Initialize(Handle<JSFunction>::null());
1752 } 1772 }
1753 } 1773 }
1754 1774
1755 1775
1756 CallOptimization::CallOptimization(Handle<JSFunction> function) { 1776 CallOptimization::CallOptimization(Handle<JSFunction> function) {
1757 Initialize(function); 1777 Initialize(function);
1758 } 1778 }
1759 1779
1760 1780
1761 int CallOptimization::GetPrototypeDepthOfExpectedType( 1781 int CallOptimization::GetPrototypeDepthOfExpectedType(
1762 Handle<JSObject> object, 1782 Handle<JSObject> object,
1763 Handle<JSObject> holder) const { 1783 Handle<JSObject> holder) const {
1764 ASSERT(is_simple_api_call()); 1784 ASSERT(is_simple_api_call());
1765 if (expected_receiver_type_.is_null()) return 0; 1785 if (expected_receiver_type_.is_null()) return 0;
1766 int depth = 0; 1786 int depth = 0;
1767 while (!object.is_identical_to(holder)) { 1787 while (!object.is_identical_to(holder)) {
1768 if (object->IsInstanceOf(*expected_receiver_type_)) return depth; 1788 if (expected_receiver_type_->IsTemplateFor(object->map())) return depth;
1769 object = Handle<JSObject>(JSObject::cast(object->GetPrototype())); 1789 object = Handle<JSObject>(JSObject::cast(object->GetPrototype()));
1770 if (!object->map()->is_hidden_prototype()) return kInvalidProtoDepth; 1790 if (!object->map()->is_hidden_prototype()) return kInvalidProtoDepth;
1771 ++depth; 1791 ++depth;
1772 } 1792 }
1773 if (holder->IsInstanceOf(*expected_receiver_type_)) return depth; 1793 if (expected_receiver_type_->IsTemplateFor(holder->map())) return depth;
1774 return kInvalidProtoDepth; 1794 return kInvalidProtoDepth;
1775 } 1795 }
1776 1796
1777 1797
1778 void CallOptimization::Initialize(Handle<JSFunction> function) { 1798 void CallOptimization::Initialize(Handle<JSFunction> function) {
1779 constant_function_ = Handle<JSFunction>::null(); 1799 constant_function_ = Handle<JSFunction>::null();
1780 is_simple_api_call_ = false; 1800 is_simple_api_call_ = false;
1781 expected_receiver_type_ = Handle<FunctionTemplateInfo>::null(); 1801 expected_receiver_type_ = Handle<FunctionTemplateInfo>::null();
1782 api_call_info_ = Handle<CallHandlerInfo>::null(); 1802 api_call_info_ = Handle<CallHandlerInfo>::null();
1783 1803
(...skipping 24 matching lines...) Expand all
1808 Handle<FunctionTemplateInfo>( 1828 Handle<FunctionTemplateInfo>(
1809 FunctionTemplateInfo::cast(signature->receiver())); 1829 FunctionTemplateInfo::cast(signature->receiver()));
1810 } 1830 }
1811 } 1831 }
1812 1832
1813 is_simple_api_call_ = true; 1833 is_simple_api_call_ = true;
1814 } 1834 }
1815 1835
1816 1836
1817 } } // namespace v8::internal 1837 } } // namespace v8::internal
OLDNEW
« include/v8-platform.h ('K') | « src/stub-cache.h ('k') | src/sweeper-thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698