| 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 |