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

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

Issue 8357010: Handlify the stub cache lookup and patching for CallIC and KeyedCallIC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 2 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 Code::Flags flags = 139 Code::Flags flags =
140 Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT); 140 Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT);
141 Handle<Object> probe(receiver->map()->FindInCodeCache(*cache_name, flags)); 141 Handle<Object> probe(receiver->map()->FindInCodeCache(*cache_name, flags));
142 if (probe->IsCode()) return Handle<Code>::cast(probe); 142 if (probe->IsCode()) return Handle<Code>::cast(probe);
143 143
144 LoadStubCompiler compiler(isolate_); 144 LoadStubCompiler compiler(isolate_);
145 Handle<Code> code = 145 Handle<Code> code =
146 compiler.CompileLoadNonexistent(cache_name, receiver, last); 146 compiler.CompileLoadNonexistent(cache_name, receiver, last);
147 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name)); 147 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name));
148 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code)); 148 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code));
149 JSObject::UpdateMapCodeCache(isolate_, receiver, cache_name, code); 149 JSObject::UpdateMapCodeCache(receiver, cache_name, code);
150 return code; 150 return code;
151 } 151 }
152 152
153 153
154 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object, 154 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
155 Handle<JSObject> holder, 155 Handle<JSObject> holder,
156 int index, 156 int index,
157 Handle<String> name) { 157 Handle<String> name) {
158 CALL_HEAP_FUNCTION(isolate(), 158 CALL_HEAP_FUNCTION(isolate(),
159 CompileLoadField(*object, *holder, index, *name), 159 CompileLoadField(*object, *holder, index, *name),
160 Code); 160 Code);
161 } 161 }
162 162
163 163
164 Handle<Code> StubCache::ComputeLoadField(Handle<String> name, 164 Handle<Code> StubCache::ComputeLoadField(Handle<String> name,
165 Handle<JSObject> receiver, 165 Handle<JSObject> receiver,
166 Handle<JSObject> holder, 166 Handle<JSObject> holder,
167 int field_index) { 167 int field_index) {
168 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 168 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
169 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD); 169 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD);
170 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 170 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
171 if (probe->IsCode()) return Handle<Code>::cast(probe); 171 if (probe->IsCode()) return Handle<Code>::cast(probe);
172 172
173 LoadStubCompiler compiler(isolate_); 173 LoadStubCompiler compiler(isolate_);
174 Handle<Code> code = 174 Handle<Code> code =
175 compiler.CompileLoadField(receiver, holder, field_index, name); 175 compiler.CompileLoadField(receiver, holder, field_index, name);
176 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 176 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
177 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 177 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
178 JSObject::UpdateMapCodeCache(isolate_, receiver, name, code); 178 JSObject::UpdateMapCodeCache(receiver, name, code);
179 return code; 179 return code;
180 } 180 }
181 181
182 182
183 Handle<Code> LoadStubCompiler::CompileLoadCallback( 183 Handle<Code> LoadStubCompiler::CompileLoadCallback(
184 Handle<String> name, 184 Handle<String> name,
185 Handle<JSObject> object, 185 Handle<JSObject> object,
186 Handle<JSObject> holder, 186 Handle<JSObject> holder,
187 Handle<AccessorInfo> callback) { 187 Handle<AccessorInfo> callback) {
188 CALL_HEAP_FUNCTION(isolate(), 188 CALL_HEAP_FUNCTION(isolate(),
(...skipping 10 matching lines...) Expand all
199 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 199 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
200 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS); 200 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
201 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 201 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
202 if (probe->IsCode()) return Handle<Code>::cast(probe); 202 if (probe->IsCode()) return Handle<Code>::cast(probe);
203 203
204 LoadStubCompiler compiler(isolate_); 204 LoadStubCompiler compiler(isolate_);
205 Handle<Code> code = 205 Handle<Code> code =
206 compiler.CompileLoadCallback(name, receiver, holder, callback); 206 compiler.CompileLoadCallback(name, receiver, holder, callback);
207 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 207 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
208 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 208 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
209 JSObject::UpdateMapCodeCache(isolate_, receiver, name, code); 209 JSObject::UpdateMapCodeCache(receiver, name, code);
210 return code; 210 return code;
211 } 211 }
212 212
213 213
214 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object, 214 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
215 Handle<JSObject> holder, 215 Handle<JSObject> holder,
216 Handle<Object> value, 216 Handle<Object> value,
217 Handle<String> name) { 217 Handle<String> name) {
218 CALL_HEAP_FUNCTION(isolate(), 218 CALL_HEAP_FUNCTION(isolate(),
219 CompileLoadConstant(*object, *holder, *value, *name), 219 CompileLoadConstant(*object, *holder, *value, *name),
220 Code); 220 Code);
221 } 221 }
222 222
223 223
224 Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name, 224 Handle<Code> StubCache::ComputeLoadConstant(Handle<String> name,
225 Handle<JSObject> receiver, 225 Handle<JSObject> receiver,
226 Handle<JSObject> holder, 226 Handle<JSObject> holder,
227 Handle<Object> value) { 227 Handle<Object> value) {
228 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 228 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
229 Code::Flags flags = 229 Code::Flags flags =
230 Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION); 230 Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION);
231 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 231 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
232 if (probe->IsCode()) return Handle<Code>::cast(probe); 232 if (probe->IsCode()) return Handle<Code>::cast(probe);
233 233
234 LoadStubCompiler compiler(isolate_); 234 LoadStubCompiler compiler(isolate_);
235 Handle<Code> code = 235 Handle<Code> code =
236 compiler.CompileLoadConstant(receiver, holder, value, name); 236 compiler.CompileLoadConstant(receiver, holder, value, name);
237 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 237 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
238 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 238 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
239 JSObject::UpdateMapCodeCache(isolate_, receiver, name, code); 239 JSObject::UpdateMapCodeCache(receiver, name, code);
240 return code; 240 return code;
241 } 241 }
242 242
243 243
244 Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> object, 244 Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> object,
245 Handle<JSObject> holder, 245 Handle<JSObject> holder,
246 Handle<String> name) { 246 Handle<String> name) {
247 CALL_HEAP_FUNCTION(isolate(), 247 CALL_HEAP_FUNCTION(isolate(),
248 CompileLoadInterceptor(*object, *holder, *name), 248 CompileLoadInterceptor(*object, *holder, *name),
249 Code); 249 Code);
250 } 250 }
251 251
252 252
253 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name, 253 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name,
254 Handle<JSObject> receiver, 254 Handle<JSObject> receiver,
255 Handle<JSObject> holder) { 255 Handle<JSObject> holder) {
256 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 256 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
257 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR); 257 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR);
258 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 258 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
259 if (probe->IsCode()) return Handle<Code>::cast(probe); 259 if (probe->IsCode()) return Handle<Code>::cast(probe);
260 260
261 LoadStubCompiler compiler(isolate_); 261 LoadStubCompiler compiler(isolate_);
262 Handle<Code> code = 262 Handle<Code> code =
263 compiler.CompileLoadInterceptor(receiver, holder, name); 263 compiler.CompileLoadInterceptor(receiver, holder, name);
264 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 264 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
265 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 265 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
266 JSObject::UpdateMapCodeCache(isolate_, receiver, name, code); 266 JSObject::UpdateMapCodeCache(receiver, name, code);
267 return code; 267 return code;
268 } 268 }
269 269
270 270
271 Handle<Code> StubCache::ComputeLoadNormal() { 271 Handle<Code> StubCache::ComputeLoadNormal() {
272 return isolate_->builtins()->LoadIC_Normal(); 272 return isolate_->builtins()->LoadIC_Normal();
273 } 273 }
274 274
275 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 275 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
276 Handle<JSObject> object, 276 Handle<JSObject> object,
(...skipping 17 matching lines...) Expand all
294 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 294 ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
295 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); 295 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
296 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 296 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
297 if (probe->IsCode()) return Handle<Code>::cast(probe); 297 if (probe->IsCode()) return Handle<Code>::cast(probe);
298 298
299 LoadStubCompiler compiler(isolate_); 299 LoadStubCompiler compiler(isolate_);
300 Handle<Code> code = 300 Handle<Code> code =
301 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); 301 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete);
302 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 302 PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
303 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 303 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
304 JSObject::UpdateMapCodeCache(isolate_, receiver, name, code); 304 JSObject::UpdateMapCodeCache(receiver, name, code);
305 return code; 305 return code;
306 } 306 }
307 307
308 308
309 MaybeObject* StubCache::ComputeKeyedLoadField(String* name, 309 MaybeObject* StubCache::ComputeKeyedLoadField(String* name,
310 JSObject* receiver, 310 JSObject* receiver,
311 JSObject* holder, 311 JSObject* holder,
312 int field_index) { 312 int field_index) {
313 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP); 313 ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
314 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD); 314 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD);
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 Code::Flags flags = Code::ComputeMonomorphicFlags( 515 Code::Flags flags = Code::ComputeMonomorphicFlags(
516 Code::STORE_IC, type, strict_mode); 516 Code::STORE_IC, type, strict_mode);
517 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 517 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
518 if (probe->IsCode()) return Handle<Code>::cast(probe); 518 if (probe->IsCode()) return Handle<Code>::cast(probe);
519 519
520 StoreStubCompiler compiler(isolate_, strict_mode); 520 StoreStubCompiler compiler(isolate_, strict_mode);
521 Handle<Code> code = 521 Handle<Code> code =
522 compiler.CompileStoreField(receiver, field_index, transition, name); 522 compiler.CompileStoreField(receiver, field_index, transition, name);
523 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); 523 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
524 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); 524 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
525 JSObject::UpdateMapCodeCache(isolate_, receiver, name, code); 525 JSObject::UpdateMapCodeCache(receiver, name, code);
526 return code; 526 return code;
527 } 527 }
528 528
529 529
530 MaybeObject* StubCache::ComputeKeyedLoadOrStoreElement( 530 MaybeObject* StubCache::ComputeKeyedLoadOrStoreElement(
531 JSObject* receiver, 531 JSObject* receiver,
532 KeyedIC::StubKind stub_kind, 532 KeyedIC::StubKind stub_kind,
533 StrictModeFlag strict_mode) { 533 StrictModeFlag strict_mode) {
534 Code::Flags flags = 534 Code::Flags flags =
535 Code::ComputeMonomorphicFlags( 535 Code::ComputeMonomorphicFlags(
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 StrictModeFlag strict_mode) { 616 StrictModeFlag strict_mode) {
617 Code::Flags flags = Code::ComputeMonomorphicFlags( 617 Code::Flags flags = Code::ComputeMonomorphicFlags(
618 Code::STORE_IC, NORMAL, strict_mode); 618 Code::STORE_IC, NORMAL, strict_mode);
619 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 619 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
620 if (probe->IsCode()) return Handle<Code>::cast(probe); 620 if (probe->IsCode()) return Handle<Code>::cast(probe);
621 621
622 StoreStubCompiler compiler(isolate_, strict_mode); 622 StoreStubCompiler compiler(isolate_, strict_mode);
623 Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name); 623 Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name);
624 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); 624 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
625 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); 625 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
626 JSObject::UpdateMapCodeCache(isolate_, receiver, name, code); 626 JSObject::UpdateMapCodeCache(receiver, name, code);
627 return code; 627 return code;
628 } 628 }
629 629
630 630
631 Handle<Code> StoreStubCompiler::CompileStoreCallback( 631 Handle<Code> StoreStubCompiler::CompileStoreCallback(
632 Handle<JSObject> object, 632 Handle<JSObject> object,
633 Handle<AccessorInfo> callback, 633 Handle<AccessorInfo> callback,
634 Handle<String> name) { 634 Handle<String> name) {
635 CALL_HEAP_FUNCTION(isolate(), 635 CALL_HEAP_FUNCTION(isolate(),
636 CompileStoreCallback(*object, *callback, *name), 636 CompileStoreCallback(*object, *callback, *name),
637 Code); 637 Code);
638 } 638 }
639 639
640 640
641 Handle<Code> StubCache::ComputeStoreCallback(Handle<String> name, 641 Handle<Code> StubCache::ComputeStoreCallback(Handle<String> name,
642 Handle<JSObject> receiver, 642 Handle<JSObject> receiver,
643 Handle<AccessorInfo> callback, 643 Handle<AccessorInfo> callback,
644 StrictModeFlag strict_mode) { 644 StrictModeFlag strict_mode) {
645 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); 645 ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
646 Code::Flags flags = Code::ComputeMonomorphicFlags( 646 Code::Flags flags = Code::ComputeMonomorphicFlags(
647 Code::STORE_IC, CALLBACKS, strict_mode); 647 Code::STORE_IC, CALLBACKS, strict_mode);
648 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 648 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
649 if (probe->IsCode()) return Handle<Code>::cast(probe); 649 if (probe->IsCode()) return Handle<Code>::cast(probe);
650 650
651 StoreStubCompiler compiler(isolate_, strict_mode); 651 StoreStubCompiler compiler(isolate_, strict_mode);
652 Handle<Code> code = compiler.CompileStoreCallback(receiver, callback, name); 652 Handle<Code> code = compiler.CompileStoreCallback(receiver, callback, name);
653 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); 653 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
654 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); 654 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
655 JSObject::UpdateMapCodeCache(isolate_, receiver, name, code); 655 JSObject::UpdateMapCodeCache(receiver, name, code);
656 return code; 656 return code;
657 } 657 }
658 658
659 659
660 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(Handle<JSObject> object, 660 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(Handle<JSObject> object,
661 Handle<String> name) { 661 Handle<String> name) {
662 CALL_HEAP_FUNCTION(isolate(), 662 CALL_HEAP_FUNCTION(isolate(),
663 CompileStoreInterceptor(*object, *name), 663 CompileStoreInterceptor(*object, *name),
664 Code); 664 Code);
665 } 665 }
666 666
667 667
668 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name, 668 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name,
669 Handle<JSObject> receiver, 669 Handle<JSObject> receiver,
670 StrictModeFlag strict_mode) { 670 StrictModeFlag strict_mode) {
671 Code::Flags flags = Code::ComputeMonomorphicFlags( 671 Code::Flags flags = Code::ComputeMonomorphicFlags(
672 Code::STORE_IC, INTERCEPTOR, strict_mode); 672 Code::STORE_IC, INTERCEPTOR, strict_mode);
673 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 673 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
674 if (probe->IsCode()) return Handle<Code>::cast(probe); 674 if (probe->IsCode()) return Handle<Code>::cast(probe);
675 675
676 StoreStubCompiler compiler(isolate_, strict_mode); 676 StoreStubCompiler compiler(isolate_, strict_mode);
677 Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name); 677 Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name);
678 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); 678 PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
679 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); 679 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
680 JSObject::UpdateMapCodeCache(isolate_, receiver, name, code); 680 JSObject::UpdateMapCodeCache(receiver, name, code);
681 return code; 681 return code;
682 } 682 }
683 683
684 684
685 MaybeObject* StubCache::ComputeKeyedStoreField(String* name, 685 MaybeObject* StubCache::ComputeKeyedStoreField(String* name,
686 JSObject* receiver, 686 JSObject* receiver,
687 int field_index, 687 int field_index,
688 Map* transition, 688 Map* transition,
689 StrictModeFlag strict_mode) { 689 StrictModeFlag strict_mode) {
690 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION; 690 PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION;
(...skipping 16 matching lines...) Expand all
707 receiver->UpdateMapCodeCache(name, Code::cast(code)); 707 receiver->UpdateMapCodeCache(name, Code::cast(code));
708 if (!maybe_result->ToObject(&result)) return maybe_result; 708 if (!maybe_result->ToObject(&result)) return maybe_result;
709 } 709 }
710 } 710 }
711 return code; 711 return code;
712 } 712 }
713 713
714 #define CALL_LOGGER_TAG(kind, type) \ 714 #define CALL_LOGGER_TAG(kind, type) \
715 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) 715 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
716 716
717 MaybeObject* StubCache::ComputeCallConstant(int argc, 717 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object,
718 Handle<JSObject> holder,
719 Handle<JSFunction> function,
720 Handle<String> name,
721 CheckType check) {
722 CALL_HEAP_FUNCTION(
723 isolate(),
724 CompileCallConstant(*object, *holder, *function, *name, check),
725 Code);
726 }
727
728
729 Handle<Code> StubCache::ComputeCallConstant(int argc,
718 Code::Kind kind, 730 Code::Kind kind,
719 Code::ExtraICState extra_ic_state, 731 Code::ExtraICState extra_state,
720 String* name, 732 Handle<String> name,
721 Object* object, 733 Handle<Object> object,
722 JSObject* holder, 734 Handle<JSObject> holder,
723 JSFunction* function) { 735 Handle<JSFunction> function) {
724 // Compute the check type and the map. 736 // Compute the check type and the map.
725 InlineCacheHolderFlag cache_holder = 737 InlineCacheHolderFlag cache_holder =
726 IC::GetCodeCacheForObject(object, holder); 738 IC::GetCodeCacheForObject(*object, *holder);
727 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); 739 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
728 740
729 // Compute check type based on receiver/holder. 741 // Compute check type based on receiver/holder.
730 CheckType check = RECEIVER_MAP_CHECK; 742 CheckType check = RECEIVER_MAP_CHECK;
731 if (object->IsString()) { 743 if (object->IsString()) {
732 check = STRING_CHECK; 744 check = STRING_CHECK;
733 } else if (object->IsNumber()) { 745 } else if (object->IsNumber()) {
734 check = NUMBER_CHECK; 746 check = NUMBER_CHECK;
735 } else if (object->IsBoolean()) { 747 } else if (object->IsBoolean()) {
736 check = BOOLEAN_CHECK; 748 check = BOOLEAN_CHECK;
737 } 749 }
738 750
739 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, 751 Code::Flags flags =
740 CONSTANT_FUNCTION, 752 Code::ComputeMonomorphicFlags(kind, CONSTANT_FUNCTION, extra_state,
741 extra_ic_state, 753 cache_holder, argc);
742 cache_holder, 754 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
743 argc); 755 if (probe->IsCode()) return Handle<Code>::cast(probe);
744 Object* code = map_holder->map()->FindInCodeCache(name, flags); 756
745 if (code->IsUndefined()) { 757 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
746 // If the function hasn't been compiled yet, we cannot do it now 758 Handle<Code> code =
747 // because it may cause GC. To avoid this issue, we return an 759 compiler.CompileCallConstant(object, holder, function, name, check);
748 // internal error which will make sure we do not update any 760 code->set_check_type(check);
749 // caches. 761 ASSERT_EQ(flags, code->flags());
750 if (!function->is_compiled()) return Failure::InternalError(); 762 PROFILE(isolate_,
751 // Compile the stub - only create stubs for fully compiled functions. 763 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
752 HandleScope scope(isolate_); 764 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
753 CallStubCompiler compiler(isolate_, 765 JSObject::UpdateMapCodeCache(map_holder, name, code);
754 argc,
755 kind,
756 extra_ic_state,
757 cache_holder);
758 { MaybeObject* maybe_code =
759 compiler.CompileCallConstant(object, holder, function, name, check);
760 if (!maybe_code->ToObject(&code)) return maybe_code;
761 }
762 Code::cast(code)->set_check_type(check);
763 ASSERT_EQ(flags, Code::cast(code)->flags());
764 PROFILE(isolate_,
765 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
766 Code::cast(code), name));
767 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code)));
768 Object* result;
769 { MaybeObject* maybe_result =
770 map_holder->UpdateMapCodeCache(name, Code::cast(code));
771 if (!maybe_result->ToObject(&result)) return maybe_result;
772 }
773 }
774 return code; 766 return code;
775 } 767 }
776 768
777 769
778 MaybeObject* StubCache::ComputeCallField(int argc, 770 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
771 Handle<JSObject> holder,
772 int index,
773 Handle<String> name) {
774 CALL_HEAP_FUNCTION(
775 isolate(),
776 CompileCallField(*object, *holder, index, *name),
777 Code);
778 }
779
780
781 Handle<Code> StubCache::ComputeCallField(int argc,
779 Code::Kind kind, 782 Code::Kind kind,
780 Code::ExtraICState extra_ic_state, 783 Code::ExtraICState extra_state,
781 String* name, 784 Handle<String> name,
782 Object* object, 785 Handle<Object> object,
783 JSObject* holder, 786 Handle<JSObject> holder,
784 int index) { 787 int index) {
785 // Compute the check type and the map. 788 // Compute the check type and the map.
786 InlineCacheHolderFlag cache_holder = 789 InlineCacheHolderFlag cache_holder =
787 IC::GetCodeCacheForObject(object, holder); 790 IC::GetCodeCacheForObject(*object, *holder);
788 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); 791 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
789 792
790 // TODO(1233596): We cannot do receiver map check for non-JS objects 793 // TODO(1233596): We cannot do receiver map check for non-JS objects
791 // because they may be represented as immediates without a 794 // because they may be represented as immediates without a
792 // map. Instead, we check against the map in the holder. 795 // map. Instead, we check against the map in the holder.
793 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 796 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
794 object = holder; 797 object = holder;
795 } 798 }
796 799
797 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, 800 Code::Flags flags =
798 FIELD, 801 Code::ComputeMonomorphicFlags(kind, FIELD, extra_state,
799 extra_ic_state, 802 cache_holder, argc);
800 cache_holder, 803 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
801 argc); 804 if (probe->IsCode()) return Handle<Code>::cast(probe);
802 Object* code = map_holder->map()->FindInCodeCache(name, flags); 805
803 if (code->IsUndefined()) { 806 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
804 HandleScope scope(isolate_); 807 Handle<Code> code =
805 CallStubCompiler compiler(isolate_, 808 compiler.CompileCallField(Handle<JSObject>::cast(object),
806 argc, 809 holder, index, name);
807 kind, 810 ASSERT_EQ(flags, code->flags());
808 extra_ic_state, 811 PROFILE(isolate_,
809 cache_holder); 812 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
810 { MaybeObject* maybe_code = 813 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
811 compiler.CompileCallField(JSObject::cast(object), 814 JSObject::UpdateMapCodeCache(map_holder, name, code);
812 holder,
813 index,
814 name);
815 if (!maybe_code->ToObject(&code)) return maybe_code;
816 }
817 ASSERT_EQ(flags, Code::cast(code)->flags());
818 PROFILE(isolate_,
819 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
820 Code::cast(code), name));
821 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code)));
822 Object* result;
823 { MaybeObject* maybe_result =
824 map_holder->UpdateMapCodeCache(name, Code::cast(code));
825 if (!maybe_result->ToObject(&result)) return maybe_result;
826 }
827 }
828 return code; 815 return code;
829 } 816 }
830 817
831 818
832 MaybeObject* StubCache::ComputeCallInterceptor( 819 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
833 int argc, 820 Handle<JSObject> holder,
834 Code::Kind kind, 821 Handle<String> name) {
835 Code::ExtraICState extra_ic_state, 822 CALL_HEAP_FUNCTION(
836 String* name, 823 isolate(),
837 Object* object, 824 CompileCallInterceptor(*object, *holder, *name),
838 JSObject* holder) { 825 Code);
826 }
827
828
829 Handle<Code> StubCache::ComputeCallInterceptor(int argc,
830 Code::Kind kind,
831 Code::ExtraICState extra_state,
832 Handle<String> name,
833 Handle<Object> object,
834 Handle<JSObject> holder) {
839 // Compute the check type and the map. 835 // Compute the check type and the map.
840 InlineCacheHolderFlag cache_holder = 836 InlineCacheHolderFlag cache_holder =
841 IC::GetCodeCacheForObject(object, holder); 837 IC::GetCodeCacheForObject(*object, *holder);
842 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); 838 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
843 839
844 // TODO(1233596): We cannot do receiver map check for non-JS objects 840 // TODO(1233596): We cannot do receiver map check for non-JS objects
845 // because they may be represented as immediates without a 841 // because they may be represented as immediates without a
846 // map. Instead, we check against the map in the holder. 842 // map. Instead, we check against the map in the holder.
847 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 843 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
848 object = holder; 844 object = holder;
849 } 845 }
850 846
851 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, 847 Code::Flags flags =
852 INTERCEPTOR, 848 Code::ComputeMonomorphicFlags(kind, INTERCEPTOR, extra_state,
853 extra_ic_state, 849 cache_holder, argc);
854 cache_holder, 850 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
855 argc); 851 if (probe->IsCode()) return Handle<Code>::cast(probe);
856 Object* code = map_holder->map()->FindInCodeCache(name, flags); 852
857 if (code->IsUndefined()) { 853 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
858 HandleScope scope(isolate()); 854 Handle<Code> code =
859 CallStubCompiler compiler(isolate(), 855 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object),
860 argc, 856 holder, name);
861 kind, 857 ASSERT_EQ(flags, code->flags());
862 extra_ic_state, 858 PROFILE(isolate(),
863 cache_holder); 859 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
864 { MaybeObject* maybe_code = 860 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
865 compiler.CompileCallInterceptor(JSObject::cast(object), holder, name); 861 JSObject::UpdateMapCodeCache(map_holder, name, code);
866 if (!maybe_code->ToObject(&code)) return maybe_code;
867 }
868 ASSERT_EQ(flags, Code::cast(code)->flags());
869 PROFILE(isolate(),
870 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
871 Code::cast(code), name));
872 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code)));
873 Object* result;
874 { MaybeObject* maybe_result =
875 map_holder->UpdateMapCodeCache(name, Code::cast(code));
876 if (!maybe_result->ToObject(&result)) return maybe_result;
877 }
878 }
879 return code; 862 return code;
880 } 863 }
881 864
882 865
883 MaybeObject* StubCache::ComputeCallNormal(int argc, 866 Handle<Code> CallStubCompiler::CompileCallGlobal(
867 Handle<JSObject> object,
868 Handle<GlobalObject> holder,
869 Handle<JSGlobalPropertyCell> cell,
870 Handle<JSFunction> function,
871 Handle<String> name) {
872 CALL_HEAP_FUNCTION(
873 isolate(),
874 CompileCallGlobal(*object, *holder, *cell, *function, *name),
875 Code);
876 }
877
878
879 Handle<Code> StubCache::ComputeCallGlobal(int argc,
884 Code::Kind kind, 880 Code::Kind kind,
885 Code::ExtraICState extra_ic_state, 881 Code::ExtraICState extra_state,
886 String* name, 882 Handle<String> name,
887 JSObject* receiver) { 883 Handle<JSObject> receiver,
888 Object* code; 884 Handle<GlobalObject> holder,
889 { MaybeObject* maybe_code = ComputeCallNormal(argc, kind, extra_ic_state); 885 Handle<JSGlobalPropertyCell> cell,
890 if (!maybe_code->ToObject(&code)) return maybe_code; 886 Handle<JSFunction> function) {
891 } 887 InlineCacheHolderFlag cache_holder =
888 IC::GetCodeCacheForObject(*receiver, *holder);
889 Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
890 Code::Flags flags =
891 Code::ComputeMonomorphicFlags(kind, NORMAL, extra_state,
892 cache_holder, argc);
893 Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
894 if (probe->IsCode()) return Handle<Code>::null();
895
896 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
897 Handle<Code> code =
898 compiler.CompileCallGlobal(receiver, holder, cell, function, name);
899 ASSERT_EQ(flags, code->flags());
900 PROFILE(isolate(),
901 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
902 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
903 JSObject::UpdateMapCodeCache(map_holder, name, code);
892 return code; 904 return code;
893 } 905 }
894 906
895 907
896 MaybeObject* StubCache::ComputeCallGlobal(int argc, 908 static void FillCache(Isolate* isolate, Handle<Code> code) {
897 Code::Kind kind, 909 Handle<NumberDictionary> dictionary =
898 Code::ExtraICState extra_ic_state, 910 NumberDictionarySet(isolate->factory()->non_monomorphic_cache(),
899 String* name, 911 code->flags(),
900 JSObject* receiver, 912 code,
901 GlobalObject* holder, 913 PropertyDetails(NONE, NORMAL));
902 JSGlobalPropertyCell* cell, 914 isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
903 JSFunction* function) {
904 InlineCacheHolderFlag cache_holder =
905 IC::GetCodeCacheForObject(receiver, holder);
906 JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder);
907 Code::Flags flags = Code::ComputeMonomorphicFlags(kind,
908 NORMAL,
909 extra_ic_state,
910 cache_holder,
911 argc);
912 Object* code = map_holder->map()->FindInCodeCache(name, flags);
913 if (code->IsUndefined()) {
914 // If the function hasn't been compiled yet, we cannot do it now
915 // because it may cause GC. To avoid this issue, we return an
916 // internal error which will make sure we do not update any
917 // caches.
918 if (!function->is_compiled()) return Failure::InternalError();
919 HandleScope scope(isolate());
920 CallStubCompiler compiler(isolate(),
921 argc,
922 kind,
923 extra_ic_state,
924 cache_holder);
925 { MaybeObject* maybe_code =
926 compiler.CompileCallGlobal(receiver, holder, cell, function, name);
927 if (!maybe_code->ToObject(&code)) return maybe_code;
928 }
929 ASSERT_EQ(flags, Code::cast(code)->flags());
930 PROFILE(isolate(),
931 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
932 Code::cast(code), name));
933 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code)));
934 Object* result;
935 { MaybeObject* maybe_result =
936 map_holder->UpdateMapCodeCache(name, Code::cast(code));
937 if (!maybe_result->ToObject(&result)) return maybe_result;
938 }
939 }
940 return code;
941 } 915 }
942 916
943 917
944 static Object* GetProbeValue(Isolate* isolate, Code::Flags flags) {
945 // Use raw_unchecked... so we don't get assert failures during GC.
946 NumberDictionary* dictionary =
947 isolate->heap()->raw_unchecked_non_monomorphic_cache();
948 int entry = dictionary->FindEntry(isolate, flags);
949 if (entry != -1) return dictionary->ValueAt(entry);
950 return isolate->heap()->raw_unchecked_undefined_value();
951 }
952
953
954 MUST_USE_RESULT static MaybeObject* ProbeCache(Isolate* isolate,
955 Code::Flags flags) {
956 Heap* heap = isolate->heap();
957 Object* probe = GetProbeValue(isolate, flags);
958 if (probe != heap->undefined_value()) return probe;
959 // Seed the cache with an undefined value to make sure that any
960 // generated code object can always be inserted into the cache
961 // without causing allocation failures.
962 Object* result;
963 { MaybeObject* maybe_result =
964 heap->non_monomorphic_cache()->AtNumberPut(flags,
965 heap->undefined_value());
966 if (!maybe_result->ToObject(&result)) return maybe_result;
967 }
968 heap->public_set_non_monomorphic_cache(NumberDictionary::cast(result));
969 return probe;
970 }
971
972
973 static MaybeObject* FillCache(Isolate* isolate, MaybeObject* maybe_code) {
974 Object* code;
975 if (maybe_code->ToObject(&code)) {
976 if (code->IsCode()) {
977 Heap* heap = isolate->heap();
978 int entry = heap->non_monomorphic_cache()->FindEntry(
979 Code::cast(code)->flags());
980 // The entry must be present see comment in ProbeCache.
981 ASSERT(entry != -1);
982 ASSERT(heap->non_monomorphic_cache()->ValueAt(entry) ==
983 heap->undefined_value());
984 heap->non_monomorphic_cache()->ValueAtPut(entry, code);
985 CHECK(GetProbeValue(isolate, Code::cast(code)->flags()) == code);
986 }
987 }
988 return maybe_code;
989 }
990
991
992 Code* StubCache::FindCallInitialize(int argc, 918 Code* StubCache::FindCallInitialize(int argc,
993 RelocInfo::Mode mode, 919 RelocInfo::Mode mode,
994 Code::Kind kind) { 920 Code::Kind kind) {
995 Code::ExtraICState extra_state = 921 Code::ExtraICState extra_state =
996 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | 922 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
997 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); 923 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
998 Code::Flags flags = Code::ComputeFlags(kind, 924 Code::Flags flags =
999 UNINITIALIZED, 925 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc);
1000 extra_state, 926
1001 NORMAL, 927 // Use raw_unchecked... so we don't get assert failures during GC.
1002 argc); 928 NumberDictionary* dictionary =
1003 Object* result = ProbeCache(isolate(), flags)->ToObjectUnchecked(); 929 isolate()->heap()->raw_unchecked_non_monomorphic_cache();
1004 ASSERT(result != heap()->undefined_value()); 930 int entry = dictionary->FindEntry(isolate(), flags);
931 ASSERT(entry != -1);
932 Object* code = dictionary->ValueAt(entry);
1005 // This might be called during the marking phase of the collector 933 // This might be called during the marking phase of the collector
1006 // hence the unchecked cast. 934 // hence the unchecked cast.
1007 return reinterpret_cast<Code*>(result); 935 return reinterpret_cast<Code*>(code);
Vyacheslav Egorov (Chromium) 2011/10/20 10:12:23 I wonder how this can be callled during marking ph
Kevin Millikin (Chromium) 2011/10/20 10:57:08 Good question, and good suggestion to switch to ch
1008 } 936 }
1009 937
1010 938
1011 MaybeObject* StubCache::ComputeCallInitialize(int argc, 939 Handle<Code> StubCache::ComputeCallInitialize(int argc,
1012 RelocInfo::Mode mode, 940 RelocInfo::Mode mode,
1013 Code::Kind kind) { 941 Code::Kind kind) {
1014 Code::ExtraICState extra_state = 942 Code::ExtraICState extra_state =
1015 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | 943 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
1016 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); 944 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
1017 Code::Flags flags = Code::ComputeFlags(kind, 945 Code::Flags flags =
1018 UNINITIALIZED, 946 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc);
1019 extra_state, 947 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
1020 NORMAL, 948 int entry = cache->FindEntry(isolate_, flags);
1021 argc); 949 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
1022 Object* probe; 950
1023 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1024 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1025 }
1026 if (!probe->IsUndefined()) return probe;
1027 HandleScope scope(isolate_);
1028 StubCompiler compiler(isolate_); 951 StubCompiler compiler(isolate_);
1029 return FillCache(isolate_, compiler.CompileCallInitialize(flags)); 952 Handle<Code> code = compiler.CompileCallInitialize(flags);
953 FillCache(isolate_, code);
954 return code;
1030 } 955 }
1031 956
1032 957
1033 Handle<Code> StubCache::ComputeCallInitialize(int argc, 958 Handle<Code> StubCache::ComputeCallInitialize(int argc, RelocInfo::Mode mode) {
1034 RelocInfo::Mode mode) { 959 return ComputeCallInitialize(argc, mode, Code::CALL_IC);
1035 CALL_HEAP_FUNCTION(isolate_,
1036 ComputeCallInitialize(argc, mode, Code::CALL_IC),
1037 Code);
1038 } 960 }
1039 961
1040 962
1041 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) { 963 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) {
1042 CALL_HEAP_FUNCTION( 964 return ComputeCallInitialize(argc, RelocInfo::CODE_TARGET, Code::KEYED_CALL_IC );
1043 isolate_,
1044 ComputeCallInitialize(argc, RelocInfo::CODE_TARGET, Code::KEYED_CALL_IC),
1045 Code);
1046 } 965 }
1047 966
1048 967
1049 MaybeObject* StubCache::ComputeCallPreMonomorphic( 968 Handle<Code> StubCache::ComputeCallPreMonomorphic(
1050 int argc, 969 int argc,
1051 Code::Kind kind, 970 Code::Kind kind,
1052 Code::ExtraICState extra_ic_state) { 971 Code::ExtraICState extra_state) {
1053 Code::Flags flags = Code::ComputeFlags(kind, 972 Code::Flags flags =
1054 PREMONOMORPHIC, 973 Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, NORMAL, argc);
1055 extra_ic_state, 974 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
1056 NORMAL, 975 int entry = cache->FindEntry(isolate_, flags);
1057 argc); 976 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
1058 Object* probe; 977
1059 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1060 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1061 }
1062 if (!probe->IsUndefined()) return probe;
1063 HandleScope scope(isolate_);
1064 StubCompiler compiler(isolate_); 978 StubCompiler compiler(isolate_);
1065 return FillCache(isolate_, compiler.CompileCallPreMonomorphic(flags)); 979 Handle<Code> code = compiler.CompileCallPreMonomorphic(flags);
980 FillCache(isolate_, code);
981 return code;
1066 } 982 }
1067 983
1068 984
1069 MaybeObject* StubCache::ComputeCallNormal(int argc, 985 Handle<Code> StubCache::ComputeCallNormal(int argc,
1070 Code::Kind kind, 986 Code::Kind kind,
1071 Code::ExtraICState extra_ic_state) { 987 Code::ExtraICState extra_state) {
1072 Code::Flags flags = Code::ComputeFlags(kind, 988 Code::Flags flags =
1073 MONOMORPHIC, 989 Code::ComputeFlags(kind, MONOMORPHIC, extra_state, NORMAL, argc);
1074 extra_ic_state, 990 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
1075 NORMAL, 991 int entry = cache->FindEntry(isolate_, flags);
1076 argc); 992 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
1077 Object* probe; 993
1078 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1079 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1080 }
1081 if (!probe->IsUndefined()) return probe;
1082 HandleScope scope(isolate_);
1083 StubCompiler compiler(isolate_); 994 StubCompiler compiler(isolate_);
1084 return FillCache(isolate_, compiler.CompileCallNormal(flags)); 995 Handle<Code> code = compiler.CompileCallNormal(flags);
996 FillCache(isolate_, code);
997 return code;
1085 } 998 }
1086 999
1087 1000
1088 MaybeObject* StubCache::ComputeCallArguments(int argc, Code::Kind kind) { 1001 Handle<Code> StubCache::ComputeCallArguments(int argc, Code::Kind kind) {
1089 ASSERT(kind == Code::KEYED_CALL_IC); 1002 ASSERT(kind == Code::KEYED_CALL_IC);
1090 Code::Flags flags = Code::ComputeFlags(kind, 1003 Code::Flags flags =
1091 MEGAMORPHIC, 1004 Code::ComputeFlags(kind, MEGAMORPHIC, Code::kNoExtraICState,
1092 Code::kNoExtraICState, 1005 NORMAL, argc);
1093 NORMAL, 1006 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
1094 argc); 1007 int entry = cache->FindEntry(isolate_, flags);
1095 Object* probe; 1008 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
1096 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); 1009
1097 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1098 }
1099 if (!probe->IsUndefined()) return probe;
1100 HandleScope scope(isolate_);
1101 StubCompiler compiler(isolate_); 1010 StubCompiler compiler(isolate_);
1102 return FillCache(isolate_, compiler.CompileCallArguments(flags)); 1011 Handle<Code> code = compiler.CompileCallArguments(flags);
1012 FillCache(isolate_, code);
1013 return code;
1103 } 1014 }
1104 1015
1105 1016
1106 MaybeObject* StubCache::ComputeCallMegamorphic( 1017 Handle<Code> StubCache::ComputeCallMegamorphic(
1107 int argc, 1018 int argc,
1108 Code::Kind kind, 1019 Code::Kind kind,
1109 Code::ExtraICState extra_ic_state) { 1020 Code::ExtraICState extra_state) {
1110 Code::Flags flags = Code::ComputeFlags(kind, 1021 Code::Flags flags =
1111 MEGAMORPHIC, 1022 Code::ComputeFlags(kind, MEGAMORPHIC, extra_state,
1112 extra_ic_state, 1023 NORMAL, argc);
1113 NORMAL, 1024 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
1114 argc); 1025 int entry = cache->FindEntry(isolate_, flags);
1115 Object* probe; 1026 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
1116 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); 1027
1117 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1118 }
1119 if (!probe->IsUndefined()) return probe;
1120 HandleScope scope(isolate_);
1121 StubCompiler compiler(isolate_); 1028 StubCompiler compiler(isolate_);
1122 return FillCache(isolate_, compiler.CompileCallMegamorphic(flags)); 1029 Handle<Code> code = compiler.CompileCallMegamorphic(flags);
1030 FillCache(isolate_, code);
1031 return code;
1123 } 1032 }
1124 1033
1125 1034
1126 MaybeObject* StubCache::ComputeCallMiss(int argc, 1035 Handle<Code> StubCache::ComputeCallMiss(int argc,
1127 Code::Kind kind, 1036 Code::Kind kind,
1128 Code::ExtraICState extra_ic_state) { 1037 Code::ExtraICState extra_state) {
1129 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs 1038 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs
1130 // and monomorphic stubs are not mixed up together in the stub cache. 1039 // and monomorphic stubs are not mixed up together in the stub cache.
1131 Code::Flags flags = Code::ComputeFlags(kind, 1040 Code::Flags flags =
1132 MONOMORPHIC_PROTOTYPE_FAILURE, 1041 Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state,
1133 extra_ic_state, 1042 NORMAL, argc, OWN_MAP);
1134 NORMAL, 1043 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
1135 argc, 1044 int entry = cache->FindEntry(isolate_, flags);
1136 OWN_MAP); 1045 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
1137 Object* probe; 1046
1138 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1139 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1140 }
1141 if (!probe->IsUndefined()) return probe;
1142 HandleScope scope(isolate_);
1143 StubCompiler compiler(isolate_); 1047 StubCompiler compiler(isolate_);
1144 return FillCache(isolate_, compiler.CompileCallMiss(flags)); 1048 Handle<Code> code = compiler.CompileCallMiss(flags);
1049 FillCache(isolate_, code);
1050 return code;
1051 }
1052
1053
1054 // The CallStubCompiler needs a version of ComputeCallMiss that does
1055 // not perform GC.
1056 MaybeObject* StubCache::TryComputeCallMiss(int argc,
Vyacheslav Egorov (Chromium) 2011/10/20 10:12:23 I wonder why ComputeCallMiss is not defined in ter
Kevin Millikin (Chromium) 2011/10/20 10:57:08 Yeah, Try... will be eliminated next. I'll commen
1057 Code::Kind kind,
1058 Code::ExtraICState extra_state) {
1059 Code::Flags flags =
1060 Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state,
1061 NORMAL, argc, OWN_MAP);
1062 NumberDictionary* cache = isolate_->heap()->non_monomorphic_cache();
1063 int entry = cache->FindEntry(isolate_, flags);
1064 if (entry != -1) return cache->ValueAt(entry);
1065
1066 StubCompiler compiler(isolate_);
1067 Code* code = NULL;
1068 MaybeObject* maybe_code = compiler.TryCompileCallMiss(flags);
1069 if (!maybe_code->To(&code)) return maybe_code;
1070
1071 NumberDictionary* new_cache = NULL;
1072 MaybeObject* maybe_new_cache = cache->AtNumberPut(flags, code);
1073 if (!maybe_new_cache->To(&new_cache)) return maybe_new_cache;
1074 isolate_->heap()->public_set_non_monomorphic_cache(new_cache);
1075
1076 return code;
1145 } 1077 }
1146 1078
1147 1079
1148 #ifdef ENABLE_DEBUGGER_SUPPORT 1080 #ifdef ENABLE_DEBUGGER_SUPPORT
1149 MaybeObject* StubCache::ComputeCallDebugBreak( 1081 Handle<Code> StubCache::ComputeCallDebugBreak(int argc,
1150 int argc, 1082 Code::Kind kind) {
1151 Code::Kind kind) {
1152 // Extra IC state is irrelevant for debug break ICs. They jump to 1083 // Extra IC state is irrelevant for debug break ICs. They jump to
1153 // the actual call ic to carry out the work. 1084 // the actual call ic to carry out the work.
1154 Code::Flags flags = Code::ComputeFlags(kind, 1085 Code::Flags flags =
1155 DEBUG_BREAK, 1086 Code::ComputeFlags(kind, DEBUG_BREAK, Code::kNoExtraICState,
1156 Code::kNoExtraICState, 1087 NORMAL, argc);
1157 NORMAL, 1088 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
1158 argc); 1089 int entry = cache->FindEntry(isolate_, flags);
1159 Object* probe; 1090 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
1160 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); 1091
1161 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1162 }
1163 if (!probe->IsUndefined()) return probe;
1164 HandleScope scope(isolate_);
1165 StubCompiler compiler(isolate_); 1092 StubCompiler compiler(isolate_);
1166 return FillCache(isolate_, compiler.CompileCallDebugBreak(flags)); 1093 Handle<Code> code = compiler.CompileCallDebugBreak(flags);
1094 FillCache(isolate_, code);
1095 return code;
1167 } 1096 }
1168 1097
1169 1098
1170 MaybeObject* StubCache::ComputeCallDebugPrepareStepIn( 1099 Handle<Code> StubCache::ComputeCallDebugPrepareStepIn(int argc,
1171 int argc, 1100 Code::Kind kind) {
1172 Code::Kind kind) {
1173 // Extra IC state is irrelevant for debug break ICs. They jump to 1101 // Extra IC state is irrelevant for debug break ICs. They jump to
1174 // the actual call ic to carry out the work. 1102 // the actual call ic to carry out the work.
1175 Code::Flags flags = Code::ComputeFlags(kind, 1103 Code::Flags flags =
1176 DEBUG_PREPARE_STEP_IN, 1104 Code::ComputeFlags(kind, DEBUG_PREPARE_STEP_IN, Code::kNoExtraICState,
1177 Code::kNoExtraICState, 1105 NORMAL, argc);
1178 NORMAL, 1106 Handle<NumberDictionary> cache = isolate_->factory()->non_monomorphic_cache();
1179 argc); 1107 int entry = cache->FindEntry(isolate_, flags);
1180 Object* probe; 1108 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
1181 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); 1109
1182 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1183 }
1184 if (!probe->IsUndefined()) return probe;
1185 HandleScope scope(isolate_);
1186 StubCompiler compiler(isolate_); 1110 StubCompiler compiler(isolate_);
1187 return FillCache(isolate_, compiler.CompileCallDebugPrepareStepIn(flags)); 1111 Handle<Code> code = compiler.CompileCallDebugPrepareStepIn(flags);
1112 FillCache(isolate_, code);
1113 return code;
1188 } 1114 }
1189 #endif 1115 #endif
1190 1116
1191 1117
1192 void StubCache::Clear() { 1118 void StubCache::Clear() {
1193 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal); 1119 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal);
1194 for (int i = 0; i < kPrimaryTableSize; i++) { 1120 for (int i = 0; i < kPrimaryTableSize; i++) {
1195 primary_[i].key = heap()->empty_string(); 1121 primary_[i].key = heap()->empty_string();
1196 primary_[i].value = empty; 1122 primary_[i].value = empty;
1197 } 1123 }
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 1368
1443 1369
1444 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) { 1370 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) {
1445 JSObject* receiver = JSObject::cast(args[0]); 1371 JSObject* receiver = JSObject::cast(args[0]);
1446 ASSERT(args.smi_at(1) >= 0); 1372 ASSERT(args.smi_at(1) >= 0);
1447 uint32_t index = args.smi_at(1); 1373 uint32_t index = args.smi_at(1);
1448 return receiver->GetElementWithInterceptor(receiver, index); 1374 return receiver->GetElementWithInterceptor(receiver, index);
1449 } 1375 }
1450 1376
1451 1377
1452 MaybeObject* StubCompiler::CompileCallInitialize(Code::Flags flags) { 1378 Handle<Code> StubCompiler::CompileCallInitialize(Code::Flags flags) {
1379 CALL_HEAP_FUNCTION(isolate(), TryCompileCallInitialize(flags), Code);
1380 }
1381
1382
1383 MaybeObject* StubCompiler::TryCompileCallInitialize(Code::Flags flags) {
1453 HandleScope scope(isolate()); 1384 HandleScope scope(isolate());
1454 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1385 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1455 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1386 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1456 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); 1387 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1457 if (kind == Code::CALL_IC) { 1388 if (kind == Code::CALL_IC) {
1458 CallIC::GenerateInitialize(masm(), argc, extra_ic_state); 1389 CallIC::GenerateInitialize(masm(), argc, extra_state);
1459 } else { 1390 } else {
1460 KeyedCallIC::GenerateInitialize(masm(), argc); 1391 KeyedCallIC::GenerateInitialize(masm(), argc);
1461 } 1392 }
1462 Object* result; 1393 Object* result;
1463 { MaybeObject* maybe_result = 1394 { MaybeObject* maybe_result =
1464 GetCodeWithFlags(flags, "CompileCallInitialize"); 1395 GetCodeWithFlags(flags, "CompileCallInitialize");
1465 if (!maybe_result->ToObject(&result)) return maybe_result; 1396 if (!maybe_result->ToObject(&result)) return maybe_result;
1466 } 1397 }
1467 isolate()->counters()->call_initialize_stubs()->Increment(); 1398 isolate()->counters()->call_initialize_stubs()->Increment();
1468 Code* code = Code::cast(result); 1399 Code* code = Code::cast(result);
1469 USE(code); 1400 USE(code);
1470 PROFILE(isolate(), 1401 PROFILE(isolate(),
1471 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG), 1402 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG),
1472 code, code->arguments_count())); 1403 code, code->arguments_count()));
1473 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, Code::cast(code))); 1404 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, Code::cast(code)));
1474 return result; 1405 return result;
1475 } 1406 }
1476 1407
1477 1408
1478 MaybeObject* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { 1409 Handle<Code> StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) {
1410 CALL_HEAP_FUNCTION(isolate(), TryCompileCallPreMonomorphic(flags), Code);
1411 }
1412
1413
1414 MaybeObject* StubCompiler::TryCompileCallPreMonomorphic(Code::Flags flags) {
1479 HandleScope scope(isolate()); 1415 HandleScope scope(isolate());
1480 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1416 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1481 // The code of the PreMonomorphic stub is the same as the code 1417 // The code of the PreMonomorphic stub is the same as the code
1482 // of the Initialized stub. They just differ on the code object flags. 1418 // of the Initialized stub. They just differ on the code object flags.
1483 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1419 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1484 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); 1420 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1485 if (kind == Code::CALL_IC) { 1421 if (kind == Code::CALL_IC) {
1486 CallIC::GenerateInitialize(masm(), argc, extra_ic_state); 1422 CallIC::GenerateInitialize(masm(), argc, extra_state);
1487 } else { 1423 } else {
1488 KeyedCallIC::GenerateInitialize(masm(), argc); 1424 KeyedCallIC::GenerateInitialize(masm(), argc);
1489 } 1425 }
1490 Object* result; 1426 Object* result;
1491 { MaybeObject* maybe_result = 1427 { MaybeObject* maybe_result =
1492 GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); 1428 GetCodeWithFlags(flags, "CompileCallPreMonomorphic");
1493 if (!maybe_result->ToObject(&result)) return maybe_result; 1429 if (!maybe_result->ToObject(&result)) return maybe_result;
1494 } 1430 }
1495 isolate()->counters()->call_premonomorphic_stubs()->Increment(); 1431 isolate()->counters()->call_premonomorphic_stubs()->Increment();
1496 Code* code = Code::cast(result); 1432 Code* code = Code::cast(result);
1497 USE(code); 1433 USE(code);
1498 PROFILE(isolate(), 1434 PROFILE(isolate(),
1499 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG), 1435 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG),
1500 code, code->arguments_count())); 1436 code, code->arguments_count()));
1501 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, Code::cast(code))); 1437 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, Code::cast(code)));
1502 return result; 1438 return result;
1503 } 1439 }
1504 1440
1505 1441
1506 MaybeObject* StubCompiler::CompileCallNormal(Code::Flags flags) { 1442 Handle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) {
1443 CALL_HEAP_FUNCTION(isolate(), TryCompileCallNormal(flags), Code);
1444 }
1445
1446
1447 MaybeObject* StubCompiler::TryCompileCallNormal(Code::Flags flags) {
1507 HandleScope scope(isolate()); 1448 HandleScope scope(isolate());
1508 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1449 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1509 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1450 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1510 if (kind == Code::CALL_IC) { 1451 if (kind == Code::CALL_IC) {
1511 // Call normal is always with a explict receiver. 1452 // Call normal is always with a explict receiver.
1512 ASSERT(!CallIC::Contextual::decode( 1453 ASSERT(!CallIC::Contextual::decode(
1513 Code::ExtractExtraICStateFromFlags(flags))); 1454 Code::ExtractExtraICStateFromFlags(flags)));
1514 CallIC::GenerateNormal(masm(), argc); 1455 CallIC::GenerateNormal(masm(), argc);
1515 } else { 1456 } else {
1516 KeyedCallIC::GenerateNormal(masm(), argc); 1457 KeyedCallIC::GenerateNormal(masm(), argc);
1517 } 1458 }
1518 Object* result; 1459 Object* result;
1519 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallNormal"); 1460 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallNormal");
1520 if (!maybe_result->ToObject(&result)) return maybe_result; 1461 if (!maybe_result->ToObject(&result)) return maybe_result;
1521 } 1462 }
1522 isolate()->counters()->call_normal_stubs()->Increment(); 1463 isolate()->counters()->call_normal_stubs()->Increment();
1523 Code* code = Code::cast(result); 1464 Code* code = Code::cast(result);
1524 USE(code); 1465 USE(code);
1525 PROFILE(isolate(), 1466 PROFILE(isolate(),
1526 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), 1467 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG),
1527 code, code->arguments_count())); 1468 code, code->arguments_count()));
1528 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, Code::cast(code))); 1469 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, Code::cast(code)));
1529 return result; 1470 return result;
1530 } 1471 }
1531 1472
1532 1473
1533 MaybeObject* StubCompiler::CompileCallMegamorphic(Code::Flags flags) { 1474 Handle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) {
1475 CALL_HEAP_FUNCTION(isolate(), TryCompileCallMegamorphic(flags), Code);
1476 }
1477
1478
1479 MaybeObject* StubCompiler::TryCompileCallMegamorphic(Code::Flags flags) {
1534 HandleScope scope(isolate()); 1480 HandleScope scope(isolate());
1535 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1481 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1536 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1482 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1537 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); 1483 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1538 if (kind == Code::CALL_IC) { 1484 if (kind == Code::CALL_IC) {
1539 CallIC::GenerateMegamorphic(masm(), argc, extra_ic_state); 1485 CallIC::GenerateMegamorphic(masm(), argc, extra_state);
1540 } else { 1486 } else {
1541 KeyedCallIC::GenerateMegamorphic(masm(), argc); 1487 KeyedCallIC::GenerateMegamorphic(masm(), argc);
1542 } 1488 }
1543 Object* result; 1489 Object* result;
1544 { MaybeObject* maybe_result = 1490 { MaybeObject* maybe_result =
1545 GetCodeWithFlags(flags, "CompileCallMegamorphic"); 1491 GetCodeWithFlags(flags, "CompileCallMegamorphic");
1546 if (!maybe_result->ToObject(&result)) return maybe_result; 1492 if (!maybe_result->ToObject(&result)) return maybe_result;
1547 } 1493 }
1548 isolate()->counters()->call_megamorphic_stubs()->Increment(); 1494 isolate()->counters()->call_megamorphic_stubs()->Increment();
1549 Code* code = Code::cast(result); 1495 Code* code = Code::cast(result);
1550 USE(code); 1496 USE(code);
1551 PROFILE(isolate(), 1497 PROFILE(isolate(),
1552 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), 1498 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG),
1553 code, code->arguments_count())); 1499 code, code->arguments_count()));
1554 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code))); 1500 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code)));
1555 return result; 1501 return result;
1556 } 1502 }
1557 1503
1558 1504
1559 MaybeObject* StubCompiler::CompileCallArguments(Code::Flags flags) { 1505 Handle<Code> StubCompiler::CompileCallArguments(Code::Flags flags) {
1506 CALL_HEAP_FUNCTION(isolate(), TryCompileCallArguments(flags), Code);
1507 }
1508
1509
1510 MaybeObject* StubCompiler::TryCompileCallArguments(Code::Flags flags) {
1560 HandleScope scope(isolate()); 1511 HandleScope scope(isolate());
1561 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1512 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1562 KeyedCallIC::GenerateNonStrictArguments(masm(), argc); 1513 KeyedCallIC::GenerateNonStrictArguments(masm(), argc);
1563 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1514 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1564 Object* result; 1515 Object* result;
1565 { MaybeObject* maybe_result = 1516 { MaybeObject* maybe_result =
1566 GetCodeWithFlags(flags, "CompileCallArguments"); 1517 GetCodeWithFlags(flags, "CompileCallArguments");
1567 if (!maybe_result->ToObject(&result)) return maybe_result; 1518 if (!maybe_result->ToObject(&result)) return maybe_result;
1568 } 1519 }
1569 Code* code = Code::cast(result); 1520 Code* code = Code::cast(result);
1570 USE(code); 1521 USE(code);
1571 PROFILE(isolate(), 1522 PROFILE(isolate(),
1572 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), 1523 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG),
1573 code, code->arguments_count())); 1524 code, code->arguments_count()));
1574 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code))); 1525 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code)));
1575 return result; 1526 return result;
1576 } 1527 }
1577 1528
1578 1529
1579 MaybeObject* StubCompiler::CompileCallMiss(Code::Flags flags) { 1530 Handle<Code> StubCompiler::CompileCallMiss(Code::Flags flags) {
1531 CALL_HEAP_FUNCTION(isolate(), TryCompileCallMiss(flags), Code);
1532 }
1533
1534
1535 MaybeObject* StubCompiler::TryCompileCallMiss(Code::Flags flags) {
1580 HandleScope scope(isolate()); 1536 HandleScope scope(isolate());
1581 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1537 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1582 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1538 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1583 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); 1539 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1584 if (kind == Code::CALL_IC) { 1540 if (kind == Code::CALL_IC) {
1585 CallIC::GenerateMiss(masm(), argc, extra_ic_state); 1541 CallIC::GenerateMiss(masm(), argc, extra_state);
1586 } else { 1542 } else {
1587 KeyedCallIC::GenerateMiss(masm(), argc); 1543 KeyedCallIC::GenerateMiss(masm(), argc);
1588 } 1544 }
1589 Object* result; 1545 Object* result;
1590 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallMiss"); 1546 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallMiss");
1591 if (!maybe_result->ToObject(&result)) return maybe_result; 1547 if (!maybe_result->ToObject(&result)) return maybe_result;
1592 } 1548 }
1593 isolate()->counters()->call_megamorphic_stubs()->Increment(); 1549 isolate()->counters()->call_megamorphic_stubs()->Increment();
1594 Code* code = Code::cast(result); 1550 Code* code = Code::cast(result);
1595 USE(code); 1551 USE(code);
1596 PROFILE(isolate(), 1552 PROFILE(isolate(),
1597 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG), 1553 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG),
1598 code, code->arguments_count())); 1554 code, code->arguments_count()));
1599 GDBJIT(AddCode(GDBJITInterface::CALL_MISS, Code::cast(code))); 1555 GDBJIT(AddCode(GDBJITInterface::CALL_MISS, Code::cast(code)));
1600 return result; 1556 return result;
1601 } 1557 }
1602 1558
1603 1559
1604 #ifdef ENABLE_DEBUGGER_SUPPORT 1560 #ifdef ENABLE_DEBUGGER_SUPPORT
1605 MaybeObject* StubCompiler::CompileCallDebugBreak(Code::Flags flags) { 1561 Handle<Code> StubCompiler::CompileCallDebugBreak(Code::Flags flags) {
1562 CALL_HEAP_FUNCTION(isolate(), TryCompileCallDebugBreak(flags), Code);
1563 }
1564
1565
1566 MaybeObject* StubCompiler::TryCompileCallDebugBreak(Code::Flags flags) {
1606 HandleScope scope(isolate()); 1567 HandleScope scope(isolate());
1607 Debug::GenerateCallICDebugBreak(masm()); 1568 Debug::GenerateCallICDebugBreak(masm());
1608 Object* result; 1569 Object* result;
1609 { MaybeObject* maybe_result = 1570 { MaybeObject* maybe_result =
1610 GetCodeWithFlags(flags, "CompileCallDebugBreak"); 1571 GetCodeWithFlags(flags, "CompileCallDebugBreak");
1611 if (!maybe_result->ToObject(&result)) return maybe_result; 1572 if (!maybe_result->ToObject(&result)) return maybe_result;
1612 } 1573 }
1613 Code* code = Code::cast(result); 1574 Code* code = Code::cast(result);
1614 USE(code); 1575 USE(code);
1615 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1576 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1616 USE(kind); 1577 USE(kind);
1617 PROFILE(isolate(), 1578 PROFILE(isolate(),
1618 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_DEBUG_BREAK_TAG), 1579 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_DEBUG_BREAK_TAG),
1619 code, code->arguments_count())); 1580 code, code->arguments_count()));
1620 return result; 1581 return result;
1621 } 1582 }
1622 1583
1623 1584
1624 MaybeObject* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { 1585 Handle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) {
1586 CALL_HEAP_FUNCTION(isolate(), TryCompileCallDebugPrepareStepIn(flags), Code);
1587 }
1588
1589
1590 MaybeObject* StubCompiler::TryCompileCallDebugPrepareStepIn(Code::Flags flags) {
1625 HandleScope scope(isolate()); 1591 HandleScope scope(isolate());
1626 // Use the same code for the the step in preparations as we do for 1592 // Use the same code for the the step in preparations as we do for
1627 // the miss case. 1593 // the miss case.
1628 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1594 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1629 Code::Kind kind = Code::ExtractKindFromFlags(flags); 1595 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1630 if (kind == Code::CALL_IC) { 1596 if (kind == Code::CALL_IC) {
1631 // For the debugger extra ic state is irrelevant. 1597 // For the debugger extra ic state is irrelevant.
1632 CallIC::GenerateMiss(masm(), argc, Code::kNoExtraICState); 1598 CallIC::GenerateMiss(masm(), argc, Code::kNoExtraICState);
1633 } else { 1599 } else {
1634 KeyedCallIC::GenerateMiss(masm(), argc); 1600 KeyedCallIC::GenerateMiss(masm(), argc);
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1765 1731
1766 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement( 1732 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement(
1767 MacroAssembler* masm) { 1733 MacroAssembler* masm) {
1768 KeyedStoreIC::GenerateSlow(masm); 1734 KeyedStoreIC::GenerateSlow(masm);
1769 } 1735 }
1770 1736
1771 1737
1772 CallStubCompiler::CallStubCompiler(Isolate* isolate, 1738 CallStubCompiler::CallStubCompiler(Isolate* isolate,
1773 int argc, 1739 int argc,
1774 Code::Kind kind, 1740 Code::Kind kind,
1775 Code::ExtraICState extra_ic_state, 1741 Code::ExtraICState extra_state,
1776 InlineCacheHolderFlag cache_holder) 1742 InlineCacheHolderFlag cache_holder)
1777 : StubCompiler(isolate), 1743 : StubCompiler(isolate),
1778 arguments_(argc), 1744 arguments_(argc),
1779 kind_(kind), 1745 kind_(kind),
1780 extra_ic_state_(extra_ic_state), 1746 extra_state_(extra_state),
1781 cache_holder_(cache_holder) { 1747 cache_holder_(cache_holder) {
1782 } 1748 }
1783 1749
1784 1750
1785 bool CallStubCompiler::HasCustomCallGenerator(JSFunction* function) { 1751 bool CallStubCompiler::HasCustomCallGenerator(JSFunction* function) {
1786 SharedFunctionInfo* info = function->shared(); 1752 SharedFunctionInfo* info = function->shared();
1787 if (info->HasBuiltinFunctionId()) { 1753 if (info->HasBuiltinFunctionId()) {
1788 BuiltinFunctionId id = info->builtin_function_id(); 1754 BuiltinFunctionId id = info->builtin_function_id();
1789 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true; 1755 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true;
1790 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) 1756 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1827 cell, 1793 cell,
1828 function, 1794 function,
1829 fname); 1795 fname);
1830 } 1796 }
1831 1797
1832 1798
1833 MaybeObject* CallStubCompiler::GetCode(PropertyType type, String* name) { 1799 MaybeObject* CallStubCompiler::GetCode(PropertyType type, String* name) {
1834 int argc = arguments_.immediate(); 1800 int argc = arguments_.immediate();
1835 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, 1801 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_,
1836 type, 1802 type,
1837 extra_ic_state_, 1803 extra_state_,
1838 cache_holder_, 1804 cache_holder_,
1839 argc); 1805 argc);
1840 return GetCodeWithFlags(flags, name); 1806 return GetCodeWithFlags(flags, name);
1841 } 1807 }
1842 1808
1843 1809
1844 MaybeObject* CallStubCompiler::GetCode(JSFunction* function) { 1810 MaybeObject* CallStubCompiler::GetCode(JSFunction* function) {
1845 String* function_name = NULL; 1811 String* function_name = NULL;
1846 if (function->shared()->name()->IsString()) { 1812 if (function->shared()->name()->IsString()) {
1847 function_name = String::cast(function->shared()->name()); 1813 function_name = String::cast(function->shared()->name());
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1925 expected_receiver_type_ = 1891 expected_receiver_type_ =
1926 FunctionTemplateInfo::cast(signature->receiver()); 1892 FunctionTemplateInfo::cast(signature->receiver());
1927 } 1893 }
1928 } 1894 }
1929 1895
1930 is_simple_api_call_ = true; 1896 is_simple_api_call_ = true;
1931 } 1897 }
1932 1898
1933 1899
1934 } } // namespace v8::internal 1900 } } // namespace v8::internal
OLDNEW
« src/stub-cache.h ('K') | « src/stub-cache.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698