OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |