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

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

Issue 140069: Store a lookup result when compiling interceptor ICs.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 4 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
« no previous file with comments | « src/heap.cc ('k') | src/ic.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 // entering the runtime system. 150 // entering the runtime system.
151 __ bind(&miss); 151 __ bind(&miss);
152 } 152 }
153 153
154 154
155 template <typename Pushable> 155 template <typename Pushable>
156 static void PushInterceptorArguments(MacroAssembler* masm, 156 static void PushInterceptorArguments(MacroAssembler* masm,
157 Register receiver, 157 Register receiver,
158 Register holder, 158 Register holder,
159 Pushable name, 159 Pushable name,
160 JSObject* holder_obj, 160 JSObject* holder_obj) {
161 Smi* lookup_hint) {
162 __ push(receiver); 161 __ push(receiver);
163 __ push(holder); 162 __ push(holder);
164 __ push(name); 163 __ push(name);
165 // TODO(367): Maybe don't push lookup_hint for LOOKUP_IN_HOLDER and/or
166 // LOOKUP_IN_PROTOTYPE, but use a special version of lookup method?
167 __ push(Immediate(lookup_hint));
168
169 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); 164 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
170 __ mov(receiver, Immediate(Handle<Object>(interceptor))); 165 __ mov(receiver, Immediate(Handle<Object>(interceptor)));
171 __ push(receiver); 166 __ push(receiver);
172 __ push(FieldOperand(receiver, InterceptorInfo::kDataOffset)); 167 __ push(FieldOperand(receiver, InterceptorInfo::kDataOffset));
173 } 168 }
174 169
175 170
176 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, 171 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
177 int index, 172 int index,
178 Register prototype) { 173 Register prototype) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 __ mov(dst, FieldOperand(src, offset)); 282 __ mov(dst, FieldOperand(src, offset));
288 } else { 283 } else {
289 // Calculate the offset into the properties array. 284 // Calculate the offset into the properties array.
290 int offset = index * kPointerSize + FixedArray::kHeaderSize; 285 int offset = index * kPointerSize + FixedArray::kHeaderSize;
291 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset)); 286 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset));
292 __ mov(dst, FieldOperand(dst, offset)); 287 __ mov(dst, FieldOperand(dst, offset));
293 } 288 }
294 } 289 }
295 290
296 291
292 template <class Pushable>
293 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
294 Register receiver,
295 Register holder,
296 Pushable name,
297 JSObject* holder_obj) {
298 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
299
300 ExternalReference ref =
301 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly));
302 __ mov(eax, Immediate(5));
303 __ mov(ebx, Immediate(ref));
304
305 CEntryStub stub;
306 __ CallStub(&stub);
307 }
308
309
310 template <class Compiler>
311 static void CompileLoadInterceptor(Compiler* compiler,
312 StubCompiler* stub_compiler,
313 MacroAssembler* masm,
314 JSObject* object,
315 JSObject* holder,
316 String* name,
317 LookupResult* lookup,
318 Register receiver,
319 Register scratch1,
320 Register scratch2,
321 Label* miss) {
322 ASSERT(holder->HasNamedInterceptor());
323 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
324
325 // Check that the receiver isn't a smi.
326 __ test(receiver, Immediate(kSmiTagMask));
327 __ j(zero, miss, not_taken);
328
329 // Check that the maps haven't changed.
330 Register reg =
331 stub_compiler->CheckPrototypes(object, receiver, holder,
332 scratch1, scratch2, name, miss);
333
334 if (lookup->IsValid() && lookup->IsCacheable()) {
335 compiler->CompileCacheable(masm,
336 stub_compiler,
337 receiver,
338 reg,
339 scratch1,
340 scratch2,
341 holder,
342 lookup,
343 name,
344 miss);
345 } else {
346 compiler->CompileRegular(masm,
347 receiver,
348 reg,
349 scratch2,
350 holder,
351 miss);
352 }
353 }
354
355
356 static void LookupPostInterceptor(JSObject* holder,
357 String* name,
358 LookupResult* lookup) {
359 holder->LocalLookupRealNamedProperty(name, lookup);
360 if (lookup->IsNotFound()) {
361 Object* proto = holder->GetPrototype();
362 if (proto != Heap::null_value()) {
363 proto->Lookup(name, lookup);
364 }
365 }
366 }
367
368
369 class LoadInterceptorCompiler BASE_EMBEDDED {
370 public:
371 explicit LoadInterceptorCompiler(Register name) : name_(name) {}
372
373 void CompileCacheable(MacroAssembler* masm,
374 StubCompiler* stub_compiler,
375 Register receiver,
376 Register holder,
377 Register scratch1,
378 Register scratch2,
379 JSObject* holder_obj,
380 LookupResult* lookup,
381 String* name,
382 Label* miss_label) {
383 AccessorInfo* callback = 0;
384 bool optimize = false;
385 // So far the most popular follow ups for interceptor loads are FIELD
386 // and CALLBACKS, so inline only them, other cases may be added
387 // later.
388 if (lookup->type() == FIELD) {
389 optimize = true;
390 } else if (lookup->type() == CALLBACKS) {
391 Object* callback_object = lookup->GetCallbackObject();
392 if (callback_object->IsAccessorInfo()) {
393 callback = AccessorInfo::cast(callback_object);
394 optimize = callback->getter() != NULL;
395 }
396 }
397
398 if (!optimize) {
399 CompileRegular(masm, receiver, holder, scratch2, holder_obj, miss_label);
400 return;
401 }
402
403 // Note: starting a frame here makes GC aware of pointers pushed below.
404 __ EnterInternalFrame();
405
406 if (lookup->type() == CALLBACKS) {
407 __ push(receiver);
408 }
409 __ push(holder);
410 __ push(name_);
411
412 CompileCallLoadPropertyWithInterceptor(masm,
413 receiver,
414 holder,
415 name_,
416 holder_obj);
417
418 Label interceptor_failed;
419 __ cmp(eax, Factory::no_interceptor_result_sentinel());
420 __ j(equal, &interceptor_failed);
421 __ LeaveInternalFrame();
422 __ ret(0);
423
424 __ bind(&interceptor_failed);
425 __ pop(name_);
426 __ pop(holder);
427 if (lookup->type() == CALLBACKS) {
428 __ pop(receiver);
429 }
430
431 __ LeaveInternalFrame();
432
433 if (lookup->type() == FIELD) {
434 holder = stub_compiler->CheckPrototypes(holder_obj, holder,
435 lookup->holder(), scratch1,
436 scratch2,
437 name,
438 miss_label);
439 stub_compiler->GenerateFastPropertyLoad(masm, eax,
440 holder, lookup->holder(),
441 lookup->GetFieldIndex());
442 __ ret(0);
443 } else {
444 ASSERT(lookup->type() == CALLBACKS);
445 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo());
446 ASSERT(callback != NULL);
447 ASSERT(callback->getter() != NULL);
448
449 Label cleanup;
450 __ pop(scratch2);
451 __ push(receiver);
452 __ push(scratch2);
453
454 holder = stub_compiler->CheckPrototypes(holder_obj, holder,
455 lookup->holder(), scratch1,
456 scratch2,
457 name,
458 &cleanup);
459
460 __ pop(scratch2); // save old return address
461 __ push(holder);
462 __ mov(holder, Immediate(Handle<AccessorInfo>(callback)));
463 __ push(holder);
464 __ push(FieldOperand(holder, AccessorInfo::kDataOffset));
465 __ push(name_);
466 __ push(scratch2); // restore old return address
467
468 ExternalReference ref =
469 ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
470 __ TailCallRuntime(ref, 5);
471
472 __ bind(&cleanup);
473 __ pop(scratch1);
474 __ pop(scratch2);
475 __ push(scratch1);
476 }
477 }
478
479
480 void CompileRegular(MacroAssembler* masm,
481 Register receiver,
482 Register holder,
483 Register scratch,
484 JSObject* holder_obj,
485 Label* miss_label) {
486 __ pop(scratch); // save old return address
487 PushInterceptorArguments(masm, receiver, holder, name_, holder_obj);
488 __ push(scratch); // restore old return address
489
490 ExternalReference ref = ExternalReference(
491 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
492 __ TailCallRuntime(ref, 5);
493 }
494
495 private:
496 Register name_;
497 };
498
499
500 class CallInterceptorCompiler BASE_EMBEDDED {
501 public:
502 explicit CallInterceptorCompiler(const ParameterCount& arguments)
503 : arguments_(arguments), argc_(arguments.immediate()) {}
504
505 void CompileCacheable(MacroAssembler* masm,
506 StubCompiler* stub_compiler,
507 Register receiver,
508 Register holder,
509 Register scratch1,
510 Register scratch2,
511 JSObject* holder_obj,
512 LookupResult* lookup,
513 String* name,
514 Label* miss_label) {
515 JSFunction* function = 0;
516 bool optimize = false;
517 // So far the most popular case for failed interceptor is
518 // CONSTANT_FUNCTION sitting below.
519 if (lookup->type() == CONSTANT_FUNCTION) {
520 function = lookup->GetConstantFunction();
521 // JSArray holder is a special case for call constant function
522 // (see the corresponding code).
523 if (function->is_compiled() && !holder_obj->IsJSArray()) {
524 optimize = true;
525 }
526 }
527
528 if (!optimize) {
529 CompileRegular(masm, receiver, holder, scratch2, holder_obj, miss_label);
530 return;
531 }
532
533 __ EnterInternalFrame();
534 __ push(holder); // save the holder
535
536 CompileCallLoadPropertyWithInterceptor(
537 masm,
538 receiver,
539 holder,
540 // Under EnterInternalFrame this refers to name.
541 Operand(ebp, (argc_ + 3) * kPointerSize),
542 holder_obj);
543
544 __ pop(receiver); // restore holder
545 __ LeaveInternalFrame();
546
547 __ cmp(eax, Factory::no_interceptor_result_sentinel());
548 Label invoke;
549 __ j(not_equal, &invoke);
550
551 stub_compiler->CheckPrototypes(holder_obj, receiver,
552 lookup->holder(), scratch1,
553 scratch2,
554 name,
555 miss_label);
556 if (lookup->holder()->IsGlobalObject()) {
557 __ mov(edx, Operand(esp, (argc_ + 1) * kPointerSize));
558 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
559 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edx);
560 }
561
562 ASSERT(function->is_compiled());
563 // Get the function and setup the context.
564 __ mov(edi, Immediate(Handle<JSFunction>(function)));
565 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
566
567 // Jump to the cached code (tail call).
568 ASSERT(function->is_compiled());
569 Handle<Code> code(function->code());
570 ParameterCount expected(function->shared()->formal_parameter_count());
571 __ InvokeCode(code, expected, arguments_,
572 RelocInfo::CODE_TARGET, JUMP_FUNCTION);
573
574 __ bind(&invoke);
575 }
576
577 void CompileRegular(MacroAssembler* masm,
578 Register receiver,
579 Register holder,
580 Register scratch,
581 JSObject* holder_obj,
582 Label* miss_label) {
583 __ EnterInternalFrame();
584
585 PushInterceptorArguments(masm,
586 receiver,
587 holder,
588 Operand(ebp, (argc_ + 3) * kPointerSize),
589 holder_obj);
590
591 ExternalReference ref = ExternalReference(
592 IC_Utility(IC::kLoadPropertyWithInterceptorForCall));
593 __ mov(eax, Immediate(5));
594 __ mov(ebx, Immediate(ref));
595
596 CEntryStub stub;
597 __ CallStub(&stub);
598
599 __ LeaveInternalFrame();
600 }
601
602 private:
603 const ParameterCount& arguments_;
604 int argc_;
605 };
606
607
297 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 608 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
298 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 609 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
299 Code* code = NULL; 610 Code* code = NULL;
300 if (kind == Code::LOAD_IC) { 611 if (kind == Code::LOAD_IC) {
301 code = Builtins::builtin(Builtins::LoadIC_Miss); 612 code = Builtins::builtin(Builtins::LoadIC_Miss);
302 } else { 613 } else {
303 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); 614 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss);
304 } 615 }
305 616
306 Handle<Code> ic(code); 617 Handle<Code> ic(code);
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 scratch1, scratch2, name, miss); 811 scratch1, scratch2, name, miss);
501 812
502 // Return the constant value. 813 // Return the constant value.
503 __ mov(eax, Handle<Object>(value)); 814 __ mov(eax, Handle<Object>(value));
504 __ ret(0); 815 __ ret(0);
505 } 816 }
506 817
507 818
508 void StubCompiler::GenerateLoadInterceptor(JSObject* object, 819 void StubCompiler::GenerateLoadInterceptor(JSObject* object,
509 JSObject* holder, 820 JSObject* holder,
510 Smi* lookup_hint, 821 LookupResult* lookup,
511 Register receiver, 822 Register receiver,
512 Register name_reg, 823 Register name_reg,
513 Register scratch1, 824 Register scratch1,
514 Register scratch2, 825 Register scratch2,
515 String* name, 826 String* name,
516 Label* miss) { 827 Label* miss) {
517 // Check that the receiver isn't a smi. 828 LoadInterceptorCompiler compiler(name_reg);
518 __ test(receiver, Immediate(kSmiTagMask)); 829 CompileLoadInterceptor(&compiler,
519 __ j(zero, miss, not_taken); 830 this,
520 831 masm(),
521 // Check that the maps haven't changed. 832 object,
522 Register reg = 833 holder,
523 CheckPrototypes(object, receiver, holder, 834 name,
524 scratch1, scratch2, name, miss); 835 lookup,
525 836 receiver,
526 // Push the arguments on the JS stack of the caller. 837 scratch1,
527 __ pop(scratch2); // remove return address 838 scratch2,
528 PushInterceptorArguments(masm(), 839 miss);
529 receiver,
530 reg,
531 name_reg,
532 holder,
533 lookup_hint);
534 __ push(scratch2); // restore return address
535
536 // Do tail-call to the runtime system.
537 ExternalReference load_ic_property =
538 ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
539 __ TailCallRuntime(load_ic_property, 6);
540 } 840 }
541 841
542 842
543 // TODO(1241006): Avoid having lazy compile stubs specialized by the 843 // TODO(1241006): Avoid having lazy compile stubs specialized by the
544 // number of arguments. It is not needed anymore. 844 // number of arguments. It is not needed anymore.
545 Object* StubCompiler::CompileLazyCompile(Code::Flags flags) { 845 Object* StubCompiler::CompileLazyCompile(Code::Flags flags) {
546 // Enter an internal frame. 846 // Enter an internal frame.
547 __ EnterInternalFrame(); 847 __ EnterInternalFrame();
548 848
549 // Push a copy of the function onto the stack. 849 // Push a copy of the function onto the stack.
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 Object* CallStubCompiler::CompileCallInterceptor(Object* object, 1042 Object* CallStubCompiler::CompileCallInterceptor(Object* object,
743 JSObject* holder, 1043 JSObject* holder,
744 String* name) { 1044 String* name) {
745 // ----------- S t a t e ------------- 1045 // ----------- S t a t e -------------
746 // ----------------------------------- 1046 // -----------------------------------
747 Label miss; 1047 Label miss;
748 1048
749 // Get the number of arguments. 1049 // Get the number of arguments.
750 const int argc = arguments().immediate(); 1050 const int argc = arguments().immediate();
751 1051
1052 LookupResult lookup;
1053 LookupPostInterceptor(holder, name, &lookup);
1054
752 // Get the receiver from the stack. 1055 // Get the receiver from the stack.
753 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1056 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
754 1057
755 // Check that the receiver isn't a smi. 1058 CallInterceptorCompiler compiler(arguments());
756 __ test(edx, Immediate(kSmiTagMask)); 1059 CompileLoadInterceptor(&compiler,
757 __ j(zero, &miss, not_taken); 1060 this,
1061 masm(),
1062 JSObject::cast(object),
1063 holder,
1064 name,
1065 &lookup,
1066 edx,
1067 ebx,
1068 ecx,
1069 &miss);
758 1070
759 // Check that maps have not changed and compute the holder register. 1071 // Restore receiver.
760 Register reg = 1072 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
761 CheckPrototypes(JSObject::cast(object), edx, holder,
762 ebx, ecx, name, &miss);
763
764 // Enter an internal frame.
765 __ EnterInternalFrame();
766
767 // Push arguments on the expression stack.
768 PushInterceptorArguments(masm(),
769 edx,
770 reg,
771 Operand(ebp, (argc + 3) * kPointerSize),
772 holder,
773 holder->InterceptorPropertyLookupHint(name));
774
775 // Perform call.
776 ExternalReference load_interceptor =
777 ExternalReference(IC_Utility(IC::kLoadInterceptorProperty));
778 __ mov(eax, Immediate(6));
779 __ mov(ebx, Immediate(load_interceptor));
780
781 CEntryStub stub;
782 __ CallStub(&stub);
783
784 // Move result to edi and restore receiver.
785 __ mov(edi, eax);
786 __ mov(edx, Operand(ebp, (argc + 2) * kPointerSize)); // receiver
787
788 // Exit frame.
789 __ LeaveInternalFrame();
790 1073
791 // Check that the function really is a function. 1074 // Check that the function really is a function.
792 __ test(edi, Immediate(kSmiTagMask)); 1075 __ test(eax, Immediate(kSmiTagMask));
793 __ j(zero, &miss, not_taken); 1076 __ j(zero, &miss, not_taken);
794 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); 1077 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
795 __ j(not_equal, &miss, not_taken); 1078 __ j(not_equal, &miss, not_taken);
796 1079
797 // Patch the receiver on the stack with the global proxy if 1080 // Patch the receiver on the stack with the global proxy if
798 // necessary. 1081 // necessary.
799 if (object->IsGlobalObject()) { 1082 if (object->IsGlobalObject()) {
800 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 1083 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
801 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 1084 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
802 } 1085 }
803 1086
804 // Invoke the function. 1087 // Invoke the function.
1088 __ mov(edi, eax);
805 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION); 1089 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION);
806 1090
807 // Handle load cache miss. 1091 // Handle load cache miss.
808 __ bind(&miss); 1092 __ bind(&miss);
809 Handle<Code> ic = ComputeCallMiss(argc); 1093 Handle<Code> ic = ComputeCallMiss(argc);
810 __ jmp(ic, RelocInfo::CODE_TARGET); 1094 __ jmp(ic, RelocInfo::CODE_TARGET);
811 1095
812 // Return the generated code. 1096 // Return the generated code.
813 return GetCode(INTERCEPTOR, name); 1097 return GetCode(INTERCEPTOR, name);
814 } 1098 }
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, 1450 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
1167 JSObject* holder, 1451 JSObject* holder,
1168 String* name) { 1452 String* name) {
1169 // ----------- S t a t e ------------- 1453 // ----------- S t a t e -------------
1170 // -- ecx : name 1454 // -- ecx : name
1171 // -- esp[0] : return address 1455 // -- esp[0] : return address
1172 // -- esp[4] : receiver 1456 // -- esp[4] : receiver
1173 // ----------------------------------- 1457 // -----------------------------------
1174 Label miss; 1458 Label miss;
1175 1459
1460 LookupResult lookup;
1461 LookupPostInterceptor(holder, name, &lookup);
1462
1176 __ mov(eax, Operand(esp, kPointerSize)); 1463 __ mov(eax, Operand(esp, kPointerSize));
1177 // TODO(368): Compile in the whole chain: all the interceptors in 1464 // TODO(368): Compile in the whole chain: all the interceptors in
1178 // prototypes and ultimate answer. 1465 // prototypes and ultimate answer.
1179 GenerateLoadInterceptor(receiver, 1466 GenerateLoadInterceptor(receiver,
1180 holder, 1467 holder,
1181 holder->InterceptorPropertyLookupHint(name), 1468 &lookup,
1182 eax, 1469 eax,
1183 ecx, 1470 ecx,
1184 edx, 1471 edx,
1185 ebx, 1472 ebx,
1186 name, 1473 name,
1187 &miss); 1474 &miss);
1188 1475
1189 __ bind(&miss); 1476 __ bind(&miss);
1190 GenerateLoadMiss(masm(), Code::LOAD_IC); 1477 GenerateLoadMiss(masm(), Code::LOAD_IC);
1191 1478
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 Label miss; 1633 Label miss;
1347 1634
1348 __ mov(eax, Operand(esp, kPointerSize)); 1635 __ mov(eax, Operand(esp, kPointerSize));
1349 __ mov(ecx, Operand(esp, 2 * kPointerSize)); 1636 __ mov(ecx, Operand(esp, 2 * kPointerSize));
1350 __ IncrementCounter(&Counters::keyed_load_interceptor, 1); 1637 __ IncrementCounter(&Counters::keyed_load_interceptor, 1);
1351 1638
1352 // Check that the name has not changed. 1639 // Check that the name has not changed.
1353 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 1640 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
1354 __ j(not_equal, &miss, not_taken); 1641 __ j(not_equal, &miss, not_taken);
1355 1642
1643 LookupResult lookup;
1644 LookupPostInterceptor(holder, name, &lookup);
1356 GenerateLoadInterceptor(receiver, 1645 GenerateLoadInterceptor(receiver,
1357 holder, 1646 holder,
1358 Smi::FromInt(JSObject::kLookupInHolder), 1647 &lookup,
1359 ecx, 1648 ecx,
1360 eax, 1649 eax,
1361 edx, 1650 edx,
1362 ebx, 1651 ebx,
1363 name, 1652 name,
1364 &miss); 1653 &miss);
1365 __ bind(&miss); 1654 __ bind(&miss);
1366 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); 1655 __ DecrementCounter(&Counters::keyed_load_interceptor, 1);
1367 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 1656 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
1368 1657
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 1736 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
1448 1737
1449 // Return the generated code. 1738 // Return the generated code.
1450 return GetCode(CALLBACKS, name); 1739 return GetCode(CALLBACKS, name);
1451 } 1740 }
1452 1741
1453 1742
1454 #undef __ 1743 #undef __
1455 1744
1456 } } // namespace v8::internal 1745 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698