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 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 // expectation. | 344 // expectation. |
345 if (f->nargs >= 0 && f->nargs != num_arguments) { | 345 if (f->nargs >= 0 && f->nargs != num_arguments) { |
346 IllegalOperation(num_arguments); | 346 IllegalOperation(num_arguments); |
347 return; | 347 return; |
348 } | 348 } |
349 | 349 |
350 // TODO(1236192): Most runtime routines don't need the number of | 350 // TODO(1236192): Most runtime routines don't need the number of |
351 // arguments passed in because it is constant. At some point we | 351 // arguments passed in because it is constant. At some point we |
352 // should remove this need and make the runtime routine entry code | 352 // should remove this need and make the runtime routine entry code |
353 // smarter. | 353 // smarter. |
354 movq(rax, Immediate(num_arguments)); | 354 Set(rax, num_arguments); |
355 movq(rbx, ExternalReference(f)); | 355 movq(rbx, ExternalReference(f)); |
356 CEntryStub ces(f->result_size); | 356 CEntryStub ces(f->result_size); |
357 CallStub(&ces); | 357 CallStub(&ces); |
358 } | 358 } |
359 | 359 |
360 | 360 |
361 void MacroAssembler::CallExternalReference(const ExternalReference& ext, | 361 void MacroAssembler::CallExternalReference(const ExternalReference& ext, |
362 int num_arguments) { | 362 int num_arguments) { |
363 movq(rax, Immediate(num_arguments)); | 363 Set(rax, num_arguments); |
364 movq(rbx, ext); | 364 movq(rbx, ext); |
365 | 365 |
366 CEntryStub stub(1); | 366 CEntryStub stub(1); |
367 CallStub(&stub); | 367 CallStub(&stub); |
368 } | 368 } |
369 | 369 |
370 | 370 |
371 void MacroAssembler::TailCallExternalReference(const ExternalReference& ext, | 371 void MacroAssembler::TailCallExternalReference(const ExternalReference& ext, |
372 int num_arguments, | 372 int num_arguments, |
373 int result_size) { | 373 int result_size) { |
374 // ----------- S t a t e ------------- | 374 // ----------- S t a t e ------------- |
375 // -- rsp[0] : return address | 375 // -- rsp[0] : return address |
376 // -- rsp[8] : argument num_arguments - 1 | 376 // -- rsp[8] : argument num_arguments - 1 |
377 // ... | 377 // ... |
378 // -- rsp[8 * num_arguments] : argument 0 (receiver) | 378 // -- rsp[8 * num_arguments] : argument 0 (receiver) |
379 // ----------------------------------- | 379 // ----------------------------------- |
380 | 380 |
381 // TODO(1236192): Most runtime routines don't need the number of | 381 // TODO(1236192): Most runtime routines don't need the number of |
382 // arguments passed in because it is constant. At some point we | 382 // arguments passed in because it is constant. At some point we |
383 // should remove this need and make the runtime routine entry code | 383 // should remove this need and make the runtime routine entry code |
384 // smarter. | 384 // smarter. |
385 movq(rax, Immediate(num_arguments)); | 385 Set(rax, num_arguments); |
386 JumpToExternalReference(ext, result_size); | 386 JumpToExternalReference(ext, result_size); |
387 } | 387 } |
388 | 388 |
389 | 389 |
390 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, | 390 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, |
391 int num_arguments, | 391 int num_arguments, |
392 int result_size) { | 392 int result_size) { |
393 TailCallExternalReference(ExternalReference(fid), num_arguments, result_size); | 393 TailCallExternalReference(ExternalReference(fid), num_arguments, result_size); |
394 } | 394 } |
395 | 395 |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 rol(kScratchRegister, Immediate(1)); | 633 rol(kScratchRegister, Immediate(1)); |
634 testl(kScratchRegister, Immediate(0x03)); | 634 testl(kScratchRegister, Immediate(0x03)); |
635 return zero; | 635 return zero; |
636 } | 636 } |
637 | 637 |
638 | 638 |
639 Condition MacroAssembler::CheckBothSmi(Register first, Register second) { | 639 Condition MacroAssembler::CheckBothSmi(Register first, Register second) { |
640 if (first.is(second)) { | 640 if (first.is(second)) { |
641 return CheckSmi(first); | 641 return CheckSmi(first); |
642 } | 642 } |
643 movl(kScratchRegister, first); | 643 ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3); |
644 orl(kScratchRegister, second); | 644 leal(kScratchRegister, Operand(first, second, times_1, 0)); |
645 testb(kScratchRegister, Immediate(kSmiTagMask)); | 645 testb(kScratchRegister, Immediate(0x03)); |
646 return zero; | 646 return zero; |
647 } | 647 } |
648 | 648 |
649 | 649 |
650 Condition MacroAssembler::CheckBothPositiveSmi(Register first, | 650 Condition MacroAssembler::CheckBothPositiveSmi(Register first, |
651 Register second) { | 651 Register second) { |
652 if (first.is(second)) { | 652 if (first.is(second)) { |
653 return CheckPositiveSmi(first); | 653 return CheckPositiveSmi(first); |
654 } | 654 } |
655 movq(kScratchRegister, first); | 655 movq(kScratchRegister, first); |
(...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1930 Register code_register, | 1930 Register code_register, |
1931 Label* done, | 1931 Label* done, |
1932 InvokeFlag flag) { | 1932 InvokeFlag flag) { |
1933 bool definitely_matches = false; | 1933 bool definitely_matches = false; |
1934 Label invoke; | 1934 Label invoke; |
1935 if (expected.is_immediate()) { | 1935 if (expected.is_immediate()) { |
1936 ASSERT(actual.is_immediate()); | 1936 ASSERT(actual.is_immediate()); |
1937 if (expected.immediate() == actual.immediate()) { | 1937 if (expected.immediate() == actual.immediate()) { |
1938 definitely_matches = true; | 1938 definitely_matches = true; |
1939 } else { | 1939 } else { |
1940 movq(rax, Immediate(actual.immediate())); | 1940 Set(rax, actual.immediate()); |
1941 if (expected.immediate() == | 1941 if (expected.immediate() == |
1942 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { | 1942 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { |
1943 // Don't worry about adapting arguments for built-ins that | 1943 // Don't worry about adapting arguments for built-ins that |
1944 // don't want that done. Skip adaption code by making it look | 1944 // don't want that done. Skip adaption code by making it look |
1945 // like we have a match between expected and actual number of | 1945 // like we have a match between expected and actual number of |
1946 // arguments. | 1946 // arguments. |
1947 definitely_matches = true; | 1947 definitely_matches = true; |
1948 } else { | 1948 } else { |
1949 movq(rbx, Immediate(expected.immediate())); | 1949 Set(rbx, expected.immediate()); |
1950 } | 1950 } |
1951 } | 1951 } |
1952 } else { | 1952 } else { |
1953 if (actual.is_immediate()) { | 1953 if (actual.is_immediate()) { |
1954 // Expected is in register, actual is immediate. This is the | 1954 // Expected is in register, actual is immediate. This is the |
1955 // case when we invoke function values without going through the | 1955 // case when we invoke function values without going through the |
1956 // IC mechanism. | 1956 // IC mechanism. |
1957 cmpq(expected.reg(), Immediate(actual.immediate())); | 1957 cmpq(expected.reg(), Immediate(actual.immediate())); |
1958 j(equal, &invoke); | 1958 j(equal, &invoke); |
1959 ASSERT(expected.reg().is(rbx)); | 1959 ASSERT(expected.reg().is(rbx)); |
1960 movq(rax, Immediate(actual.immediate())); | 1960 Set(rax, actual.immediate()); |
1961 } else if (!expected.reg().is(actual.reg())) { | 1961 } else if (!expected.reg().is(actual.reg())) { |
1962 // Both expected and actual are in (different) registers. This | 1962 // Both expected and actual are in (different) registers. This |
1963 // is the case when we invoke functions using call and apply. | 1963 // is the case when we invoke functions using call and apply. |
1964 cmpq(expected.reg(), actual.reg()); | 1964 cmpq(expected.reg(), actual.reg()); |
1965 j(equal, &invoke); | 1965 j(equal, &invoke); |
1966 ASSERT(actual.reg().is(rax)); | 1966 ASSERT(actual.reg().is(rax)); |
1967 ASSERT(expected.reg().is(rbx)); | 1967 ASSERT(expected.reg().is(rbx)); |
1968 } | 1968 } |
1969 } | 1969 } |
1970 | 1970 |
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2755 CPU::FlushICache(address_, size_); | 2755 CPU::FlushICache(address_, size_); |
2756 | 2756 |
2757 // Check that the code was patched as expected. | 2757 // Check that the code was patched as expected. |
2758 ASSERT(masm_.pc_ == address_ + size_); | 2758 ASSERT(masm_.pc_ == address_ + size_); |
2759 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2759 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
2760 } | 2760 } |
2761 | 2761 |
2762 } } // namespace v8::internal | 2762 } } // namespace v8::internal |
2763 | 2763 |
2764 #endif // V8_TARGET_ARCH_X64 | 2764 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |