OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 template <typename Pushable> | 136 template <typename Pushable> |
137 static void PushInterceptorArguments(MacroAssembler* masm, | 137 static void PushInterceptorArguments(MacroAssembler* masm, |
138 Register receiver, | 138 Register receiver, |
139 Register holder, | 139 Register holder, |
140 Pushable name, | 140 Pushable name, |
141 JSObject* holder_obj) { | 141 JSObject* holder_obj) { |
142 __ push(receiver); | 142 __ push(receiver); |
143 __ push(holder); | 143 __ push(holder); |
144 __ push(name); | 144 __ push(name); |
145 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); | 145 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); |
| 146 ASSERT(!Heap::InNewSpace(interceptor)); |
146 __ movq(kScratchRegister, Handle<Object>(interceptor), | 147 __ movq(kScratchRegister, Handle<Object>(interceptor), |
147 RelocInfo::EMBEDDED_OBJECT); | 148 RelocInfo::EMBEDDED_OBJECT); |
148 __ push(kScratchRegister); | 149 __ push(kScratchRegister); |
149 __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset)); | 150 __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset)); |
150 } | 151 } |
151 | 152 |
152 | 153 |
153 void StubCache::GenerateProbe(MacroAssembler* masm, | 154 void StubCache::GenerateProbe(MacroAssembler* masm, |
154 Code::Flags flags, | 155 Code::Flags flags, |
155 Register receiver, | 156 Register receiver, |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 Register receiver, | 364 Register receiver, |
364 Register result, | 365 Register result, |
365 Register scratch, | 366 Register scratch, |
366 Label* miss_label) { | 367 Label* miss_label) { |
367 __ TryGetFunctionPrototype(receiver, result, miss_label); | 368 __ TryGetFunctionPrototype(receiver, result, miss_label); |
368 if (!result.is(rax)) __ movq(rax, result); | 369 if (!result.is(rax)) __ movq(rax, result); |
369 __ ret(0); | 370 __ ret(0); |
370 } | 371 } |
371 | 372 |
372 | 373 |
373 static void LookupPostInterceptor(JSObject* holder, | 374 template <class Compiler> |
374 String* name, | 375 static void CompileLoadInterceptor(Compiler* compiler, |
375 LookupResult* lookup) { | 376 StubCompiler* stub_compiler, |
376 holder->LocalLookupRealNamedProperty(name, lookup); | 377 MacroAssembler* masm, |
377 if (lookup->IsNotFound()) { | 378 JSObject* object, |
378 Object* proto = holder->GetPrototype(); | 379 JSObject* holder, |
379 if (proto != Heap::null_value()) { | 380 String* name, |
380 proto->Lookup(name, lookup); | 381 LookupResult* lookup, |
381 } | 382 Register receiver, |
| 383 Register scratch1, |
| 384 Register scratch2, |
| 385 Label* miss) { |
| 386 ASSERT(holder->HasNamedInterceptor()); |
| 387 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |
| 388 |
| 389 // Check that the receiver isn't a smi. |
| 390 __ JumpIfSmi(receiver, miss); |
| 391 |
| 392 // Check that the maps haven't changed. |
| 393 Register reg = |
| 394 stub_compiler->CheckPrototypes(object, receiver, holder, |
| 395 scratch1, scratch2, name, miss); |
| 396 |
| 397 if (lookup->IsValid() && lookup->IsCacheable()) { |
| 398 compiler->CompileCacheable(masm, |
| 399 stub_compiler, |
| 400 receiver, |
| 401 reg, |
| 402 scratch1, |
| 403 scratch2, |
| 404 holder, |
| 405 lookup, |
| 406 name, |
| 407 miss); |
| 408 } else { |
| 409 compiler->CompileRegular(masm, |
| 410 receiver, |
| 411 reg, |
| 412 scratch2, |
| 413 holder, |
| 414 miss); |
382 } | 415 } |
383 } | 416 } |
384 | 417 |
385 | 418 |
386 class LoadInterceptorCompiler BASE_EMBEDDED { | 419 class LoadInterceptorCompiler BASE_EMBEDDED { |
387 public: | 420 public: |
388 explicit LoadInterceptorCompiler(Register name) : name_(name) {} | 421 explicit LoadInterceptorCompiler(Register name) : name_(name) {} |
389 | 422 |
390 void CompileCacheable(MacroAssembler* masm, | 423 void CompileCacheable(MacroAssembler* masm, |
391 StubCompiler* stub_compiler, | 424 StubCompiler* stub_compiler, |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 ExternalReference ref = ExternalReference( | 544 ExternalReference ref = ExternalReference( |
512 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad)); | 545 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad)); |
513 __ TailCallRuntime(ref, 5, 1); | 546 __ TailCallRuntime(ref, 5, 1); |
514 } | 547 } |
515 | 548 |
516 private: | 549 private: |
517 Register name_; | 550 Register name_; |
518 }; | 551 }; |
519 | 552 |
520 | 553 |
521 template <class Compiler> | |
522 static void CompileLoadInterceptor(Compiler* compiler, | |
523 StubCompiler* stub_compiler, | |
524 MacroAssembler* masm, | |
525 JSObject* object, | |
526 JSObject* holder, | |
527 String* name, | |
528 LookupResult* lookup, | |
529 Register receiver, | |
530 Register scratch1, | |
531 Register scratch2, | |
532 Label* miss) { | |
533 ASSERT(holder->HasNamedInterceptor()); | |
534 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); | |
535 | |
536 // Check that the receiver isn't a smi. | |
537 __ JumpIfSmi(receiver, miss); | |
538 | |
539 // Check that the maps haven't changed. | |
540 Register reg = | |
541 stub_compiler->CheckPrototypes(object, receiver, holder, | |
542 scratch1, scratch2, name, miss); | |
543 | |
544 if (lookup->IsValid() && lookup->IsCacheable()) { | |
545 compiler->CompileCacheable(masm, | |
546 stub_compiler, | |
547 receiver, | |
548 reg, | |
549 scratch1, | |
550 scratch2, | |
551 holder, | |
552 lookup, | |
553 name, | |
554 miss); | |
555 } else { | |
556 compiler->CompileRegular(masm, | |
557 receiver, | |
558 reg, | |
559 scratch2, | |
560 holder, | |
561 miss); | |
562 } | |
563 } | |
564 | |
565 | |
566 class CallInterceptorCompiler BASE_EMBEDDED { | 554 class CallInterceptorCompiler BASE_EMBEDDED { |
567 public: | 555 public: |
568 explicit CallInterceptorCompiler(const ParameterCount& arguments) | 556 explicit CallInterceptorCompiler(const ParameterCount& arguments) |
569 : arguments_(arguments), argc_(arguments.immediate()) {} | 557 : arguments_(arguments), argc_(arguments.immediate()) {} |
570 | 558 |
571 void CompileCacheable(MacroAssembler* masm, | 559 void CompileCacheable(MacroAssembler* masm, |
572 StubCompiler* stub_compiler, | 560 StubCompiler* stub_compiler, |
573 Register receiver, | 561 Register receiver, |
574 Register holder, | 562 Register holder, |
575 Register scratch1, | 563 Register scratch1, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 612 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
625 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdx); | 613 __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdx); |
626 } | 614 } |
627 | 615 |
628 ASSERT(function->is_compiled()); | 616 ASSERT(function->is_compiled()); |
629 // Get the function and setup the context. | 617 // Get the function and setup the context. |
630 __ Move(rdi, Handle<JSFunction>(function)); | 618 __ Move(rdi, Handle<JSFunction>(function)); |
631 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 619 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
632 | 620 |
633 // Jump to the cached code (tail call). | 621 // Jump to the cached code (tail call). |
634 ASSERT(function->is_compiled()); | |
635 Handle<Code> code(function->code()); | 622 Handle<Code> code(function->code()); |
636 ParameterCount expected(function->shared()->formal_parameter_count()); | 623 ParameterCount expected(function->shared()->formal_parameter_count()); |
637 __ InvokeCode(code, expected, arguments_, | 624 __ InvokeCode(code, expected, arguments_, |
638 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 625 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
639 | 626 |
640 __ bind(&invoke); | 627 __ bind(&invoke); |
641 } | 628 } |
642 | 629 |
643 void CompileRegular(MacroAssembler* masm, | 630 void CompileRegular(MacroAssembler* masm, |
644 Register receiver, | 631 Register receiver, |
(...skipping 1245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1890 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 1877 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
1891 | 1878 |
1892 // Return the generated code. | 1879 // Return the generated code. |
1893 return GetCode(); | 1880 return GetCode(); |
1894 } | 1881 } |
1895 | 1882 |
1896 | 1883 |
1897 #undef __ | 1884 #undef __ |
1898 | 1885 |
1899 } } // namespace v8::internal | 1886 } } // namespace v8::internal |
OLD | NEW |