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

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

Issue 2282001: Various refactorings in interceptor calling and loading. (Closed)
Patch Set: Addressing Soeren's comments Created 10 years, 7 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
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | test/cctest/test-api.cc » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 optimize = callback->getter() != NULL; 448 optimize = callback->getter() != NULL;
449 } 449 }
450 } 450 }
451 451
452 if (!optimize) { 452 if (!optimize) {
453 CompileRegular(masm, receiver, holder, scratch2, interceptor_holder, 453 CompileRegular(masm, receiver, holder, scratch2, interceptor_holder,
454 miss_label); 454 miss_label);
455 return; 455 return;
456 } 456 }
457 457
458 // Note: starting a frame here makes GC aware of pointers pushed below. 458 // Save necessary data before invoking an interceptor.
459 // Requires a frame to make GC aware of pushed pointers.
459 __ EnterInternalFrame(); 460 __ EnterInternalFrame();
460 461
461 if (lookup->type() == CALLBACKS) { 462 if (lookup->type() == CALLBACKS && !receiver.is(holder)) {
463 // CALLBACKS case needs a receiver to be passed into C++ callback.
462 __ push(receiver); 464 __ push(receiver);
463 } 465 }
464 __ push(holder); 466 __ push(holder);
465 __ push(name_); 467 __ push(name_);
466 468
467 // Invoke an interceptor. Note: map checks from receiver to 469 // Invoke an interceptor. Note: map checks from receiver to
468 // interceptor's holder has been compiled before (see a caller 470 // interceptor's holder has been compiled before (see a caller
469 // of this method.) 471 // of this method.)
470 CompileCallLoadPropertyWithInterceptor(masm, 472 CompileCallLoadPropertyWithInterceptor(masm,
471 receiver, 473 receiver,
472 holder, 474 holder,
473 name_, 475 name_,
474 interceptor_holder); 476 interceptor_holder);
475 477
476 // Check if interceptor provided a value for property. If it's 478 // Check if interceptor provided a value for property. If it's
477 // the case, return immediately. 479 // the case, return immediately.
478 Label interceptor_failed; 480 Label interceptor_failed;
479 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 481 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
480 __ j(equal, &interceptor_failed); 482 __ j(equal, &interceptor_failed);
481 __ LeaveInternalFrame(); 483 __ LeaveInternalFrame();
482 __ ret(0); 484 __ ret(0);
483 485
484 __ bind(&interceptor_failed); 486 __ bind(&interceptor_failed);
485 __ pop(name_); 487 __ pop(name_);
486 __ pop(holder); 488 __ pop(holder);
487 if (lookup->type() == CALLBACKS) { 489 if (lookup->type() == CALLBACKS && !receiver.is(holder)) {
488 __ pop(receiver); 490 __ pop(receiver);
489 } 491 }
490 492
491 __ LeaveInternalFrame(); 493 __ LeaveInternalFrame();
492 494
493 if (lookup->type() == FIELD) { 495 // Check that the maps from interceptor's holder to lookup's holder
494 // We found FIELD property in prototype chain of interceptor's holder. 496 // haven't changed. And load lookup's holder into |holder| register.
495 // Check that the maps from interceptor's holder to field's holder 497 if (interceptor_holder != lookup->holder()) {
496 // haven't changed... 498 holder = stub_compiler->CheckPrototypes(interceptor_holder, holder,
497 holder = stub_compiler->CheckPrototypes(interceptor_holder, 499 lookup->holder(), scratch1,
498 holder,
499 lookup->holder(),
500 scratch1,
501 scratch2, 500 scratch2,
502 name, 501 name,
503 miss_label); 502 miss_label);
504 // ... and retrieve a field from field's holder. 503 }
504
505 if (lookup->type() == FIELD) {
506 // We found FIELD property in prototype chain of interceptor's holder.
507 // Retrieve a field from field's holder.
505 stub_compiler->GenerateFastPropertyLoad(masm, 508 stub_compiler->GenerateFastPropertyLoad(masm,
506 rax, 509 rax,
507 holder, 510 holder,
508 lookup->holder(), 511 lookup->holder(),
509 lookup->GetFieldIndex()); 512 lookup->GetFieldIndex());
510 __ ret(0); 513 __ ret(0);
511 } else { 514 } else {
512 // We found CALLBACKS property in prototype chain of interceptor's 515 // We found CALLBACKS property in prototype chain of interceptor's
513 // holder. 516 // holder.
514 ASSERT(lookup->type() == CALLBACKS); 517 ASSERT(lookup->type() == CALLBACKS);
515 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); 518 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo());
516 ASSERT(callback != NULL); 519 ASSERT(callback != NULL);
517 ASSERT(callback->getter() != NULL); 520 ASSERT(callback->getter() != NULL);
518 521
519 // Prepare for tail call. Push receiver to stack after return address. 522 // Tail call to runtime.
520 Label cleanup; 523 // Important invariant in CALLBACKS case: the code above must be
524 // structured to never clobber |receiver| register.
521 __ pop(scratch2); // return address 525 __ pop(scratch2); // return address
522 __ push(receiver); 526 __ push(receiver);
523 __ push(scratch2);
524
525 // Check that the maps from interceptor's holder to callback's holder
526 // haven't changed.
527 holder = stub_compiler->CheckPrototypes(interceptor_holder, holder,
528 lookup->holder(), scratch1,
529 scratch2,
530 name,
531 &cleanup);
532
533 // Continue tail call preparation: push remaining parameters after
534 // return address.
535 __ pop(scratch2); // return address
536 __ push(holder); 527 __ push(holder);
537 __ Move(holder, Handle<AccessorInfo>(callback)); 528 __ Move(holder, Handle<AccessorInfo>(callback));
538 __ push(holder); 529 __ push(holder);
539 __ push(FieldOperand(holder, AccessorInfo::kDataOffset)); 530 __ push(FieldOperand(holder, AccessorInfo::kDataOffset));
540 __ push(name_); 531 __ push(name_);
541 __ push(scratch2); // restore return address 532 __ push(scratch2); // restore return address
542 533
543 // Tail call to runtime.
544 ExternalReference ref = 534 ExternalReference ref =
545 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); 535 ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
546 __ TailCallExternalReference(ref, 5, 1); 536 __ TailCallExternalReference(ref, 5, 1);
547
548 // Clean up code: we pushed receiver after return address and
549 // need to remove it from there.
550 __ bind(&cleanup);
551 __ pop(scratch1); // return address
552 __ pop(scratch2); // receiver
553 __ push(scratch1);
554 } 537 }
555 } 538 }
556 539
557 540
558 void CompileRegular(MacroAssembler* masm, 541 void CompileRegular(MacroAssembler* masm,
559 Register receiver, 542 Register receiver,
560 Register holder, 543 Register holder,
561 Register scratch, 544 Register scratch,
562 JSObject* interceptor_holder, 545 JSObject* interceptor_holder,
563 Label* miss_label) { 546 Label* miss_label) {
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 if (can_do_fast_api_call) { 737 if (can_do_fast_api_call) {
755 __ IncrementCounter(&Counters::call_const_interceptor_fast_api, 1); 738 __ IncrementCounter(&Counters::call_const_interceptor_fast_api, 1);
756 ReserveSpaceForFastApiCall(masm, scratch1); 739 ReserveSpaceForFastApiCall(masm, scratch1);
757 } 740 }
758 741
759 // Check that the maps from receiver to interceptor's holder 742 // Check that the maps from receiver to interceptor's holder
760 // haven't changed and thus we can invoke interceptor. 743 // haven't changed and thus we can invoke interceptor.
761 Label miss_cleanup; 744 Label miss_cleanup;
762 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; 745 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label;
763 Register holder = 746 Register holder =
764 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, 747 stub_compiler_->CheckPrototypes(object, receiver,
765 scratch1, scratch2, name, 748 interceptor_holder, scratch1,
766 depth1, miss); 749 scratch2, name, depth1, miss);
767 750
768 // Invoke an interceptor and if it provides a value, 751 // Invoke an interceptor and if it provides a value,
769 // branch to |regular_invoke|. 752 // branch to |regular_invoke|.
770 Label regular_invoke; 753 Label regular_invoke;
771 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, 754 LoadWithInterceptor(masm, receiver, holder, interceptor_holder,
772 &regular_invoke); 755 &regular_invoke);
773 756
774 // Interceptor returned nothing for this property. Try to use cached 757 // Interceptor returned nothing for this property. Try to use cached
775 // constant function. 758 // constant function.
776 759
777 // Check that the maps from interceptor's holder to constant function's 760 // Check that the maps from interceptor's holder to constant function's
778 // holder haven't changed and thus we can use cached constant function. 761 // holder haven't changed and thus we can use cached constant function.
779 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, 762 if (interceptor_holder != lookup->holder()) {
780 lookup->holder(), 763 stub_compiler_->CheckPrototypes(interceptor_holder, receiver,
781 scratch1, scratch2, name, 764 lookup->holder(), scratch1,
782 depth2, miss); 765 scratch2, name, depth2, miss);
766 // CheckPrototypes has a side effect of fetching a 'holder'
767 // for API (object which is instanceof for the signature). It's
768 // safe to omit it here, as if present, it should be fetched
769 // by the previous CheckPrototypes.
770 ASSERT((depth2 == kInvalidProtoDepth) || (depth1 != kInvalidProtoDepth));
771 }
783 772
784 // Invoke function. 773 // Invoke function.
785 if (can_do_fast_api_call) { 774 if (can_do_fast_api_call) {
786 GenerateFastApiCall(masm, optimization, arguments_.immediate()); 775 GenerateFastApiCall(masm, optimization, arguments_.immediate());
787 } else { 776 } else {
788 __ InvokeFunction(optimization.constant_function(), arguments_, 777 __ InvokeFunction(optimization.constant_function(), arguments_,
789 JUMP_FUNCTION); 778 JUMP_FUNCTION);
790 } 779 }
791 780
792 // Deferred code for fast API call case---clean preallocated space. 781 // Deferred code for fast API call case---clean preallocated space.
(...skipping 1598 matching lines...) Expand 10 before | Expand all | Expand 10 after
2391 // Return the generated code. 2380 // Return the generated code.
2392 return GetCode(); 2381 return GetCode();
2393 } 2382 }
2394 2383
2395 2384
2396 #undef __ 2385 #undef __
2397 2386
2398 } } // namespace v8::internal 2387 } } // namespace v8::internal
2399 2388
2400 #endif // V8_TARGET_ARCH_X64 2389 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698