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

Side by Side Diff: src/x64/macro-assembler-x64.cc

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 years, 10 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/x64/macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.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 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 21 matching lines...) Expand all
32 #include "assembler-x64.h" 32 #include "assembler-x64.h"
33 #include "macro-assembler-x64.h" 33 #include "macro-assembler-x64.h"
34 #include "serialize.h" 34 #include "serialize.h"
35 #include "debug.h" 35 #include "debug.h"
36 36
37 namespace v8 { 37 namespace v8 {
38 namespace internal { 38 namespace internal {
39 39
40 MacroAssembler::MacroAssembler(void* buffer, int size) 40 MacroAssembler::MacroAssembler(void* buffer, int size)
41 : Assembler(buffer, size), 41 : Assembler(buffer, size),
42 unresolved_(0),
43 generating_stub_(false), 42 generating_stub_(false),
44 allow_stub_calls_(true), 43 allow_stub_calls_(true),
45 code_object_(Heap::undefined_value()) { 44 code_object_(Heap::undefined_value()) {
46 } 45 }
47 46
48 47
49 void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) { 48 void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) {
50 movq(destination, Operand(r13, index << kPointerSizeLog2)); 49 movq(destination, Operand(r13, index << kPointerSizeLog2));
51 } 50 }
52 51
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 // arguments passed in because it is constant. At some point we 379 // arguments passed in because it is constant. At some point we
381 // should remove this need and make the runtime routine entry code 380 // should remove this need and make the runtime routine entry code
382 // smarter. 381 // smarter.
383 movq(rax, Immediate(num_arguments)); 382 movq(rax, Immediate(num_arguments));
384 movq(rbx, ExternalReference(f)); 383 movq(rbx, ExternalReference(f));
385 CEntryStub ces(f->result_size); 384 CEntryStub ces(f->result_size);
386 CallStub(&ces); 385 CallStub(&ces);
387 } 386 }
388 387
389 388
389 void MacroAssembler::CallExternalReference(const ExternalReference& ext,
390 int num_arguments) {
391 movq(rax, Immediate(num_arguments));
392 movq(rbx, ext);
393
394 CEntryStub stub(1);
395 CallStub(&stub);
396 }
397
398
390 void MacroAssembler::TailCallRuntime(ExternalReference const& ext, 399 void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
391 int num_arguments, 400 int num_arguments,
392 int result_size) { 401 int result_size) {
393 // ----------- S t a t e ------------- 402 // ----------- S t a t e -------------
394 // -- rsp[0] : return address 403 // -- rsp[0] : return address
395 // -- rsp[8] : argument num_arguments - 1 404 // -- rsp[8] : argument num_arguments - 1
396 // ... 405 // ...
397 // -- rsp[8 * num_arguments] : argument 0 (receiver) 406 // -- rsp[8 * num_arguments] : argument 0 (receiver)
398 // ----------------------------------- 407 // -----------------------------------
399 408
400 // TODO(1236192): Most runtime routines don't need the number of 409 // TODO(1236192): Most runtime routines don't need the number of
401 // arguments passed in because it is constant. At some point we 410 // arguments passed in because it is constant. At some point we
402 // should remove this need and make the runtime routine entry code 411 // should remove this need and make the runtime routine entry code
403 // smarter. 412 // smarter.
404 movq(rax, Immediate(num_arguments)); 413 movq(rax, Immediate(num_arguments));
405 JumpToRuntime(ext, result_size); 414 JumpToRuntime(ext, result_size);
406 } 415 }
407 416
408 417
409 void MacroAssembler::JumpToRuntime(const ExternalReference& ext, 418 void MacroAssembler::JumpToRuntime(const ExternalReference& ext,
410 int result_size) { 419 int result_size) {
411 // Set the entry point and jump to the C entry runtime stub. 420 // Set the entry point and jump to the C entry runtime stub.
412 movq(rbx, ext); 421 movq(rbx, ext);
413 CEntryStub ces(result_size); 422 CEntryStub ces(result_size);
414 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 423 jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
415 } 424 }
416 425
417 426
427 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
428 // Calls are not allowed in some stubs.
429 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
430
431 // Rely on the assertion to check that the number of provided
432 // arguments match the expected number of arguments. Fake a
433 // parameter count to avoid emitting code to do the check.
434 ParameterCount expected(0);
435 GetBuiltinEntry(rdx, id);
436 InvokeCode(rdx, expected, expected, flag);
437 }
438
439
418 void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { 440 void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
419 bool resolved; 441 // Load the JavaScript builtin function from the builtins object.
420 Handle<Code> code = ResolveBuiltin(id, &resolved); 442 movq(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
421 443 movq(rdi, FieldOperand(rdi, GlobalObject::kBuiltinsOffset));
422 const char* name = Builtins::GetName(id); 444 int builtins_offset =
423 int argc = Builtins::GetArgumentsCount(id); 445 JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
424 446 movq(rdi, FieldOperand(rdi, builtins_offset));
425 movq(target, code, RelocInfo::EMBEDDED_OBJECT); 447 // Load the code entry point from the function into the target register.
426 if (!resolved) { 448 movq(target, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
427 uint32_t flags = 449 movq(target, FieldOperand(target, SharedFunctionInfo::kCodeOffset));
428 Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
429 Bootstrapper::FixupFlagsUseCodeObject::encode(true);
430 Unresolved entry = { pc_offset() - sizeof(intptr_t), flags, name };
431 unresolved_.Add(entry);
432 }
433 addq(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); 450 addq(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
434 } 451 }
435 452
436 Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
437 bool* resolved) {
438 // Move the builtin function into the temporary function slot by
439 // reading it from the builtins object. NOTE: We should be able to
440 // reduce this to two instructions by putting the function table in
441 // the global object instead of the "builtins" object and by using a
442 // real register for the function.
443 movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
444 movq(rdx, FieldOperand(rdx, GlobalObject::kBuiltinsOffset));
445 int builtins_offset =
446 JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
447 movq(rdi, FieldOperand(rdx, builtins_offset));
448 453
449 return Builtins::GetCode(id, resolved);
450 }
451
452
453 void MacroAssembler::Set(Register dst, int64_t x) { 454 void MacroAssembler::Set(Register dst, int64_t x) {
454 if (x == 0) { 455 if (x == 0) {
455 xor_(dst, dst); 456 xor_(dst, dst);
456 } else if (is_int32(x)) { 457 } else if (is_int32(x)) {
457 movq(dst, Immediate(static_cast<int32_t>(x))); 458 movq(dst, Immediate(static_cast<int32_t>(x)));
458 } else if (is_uint32(x)) { 459 } else if (is_uint32(x)) {
459 movl(dst, Immediate(static_cast<uint32_t>(x))); 460 movl(dst, Immediate(static_cast<uint32_t>(x)));
460 } else { 461 } else {
461 movq(dst, x, RelocInfo::NONE); 462 movq(dst, x, RelocInfo::NONE);
462 } 463 }
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 Label* fail, 1591 Label* fail,
1591 bool is_heap_object) { 1592 bool is_heap_object) {
1592 if (!is_heap_object) { 1593 if (!is_heap_object) {
1593 JumpIfSmi(obj, fail); 1594 JumpIfSmi(obj, fail);
1594 } 1595 }
1595 Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 1596 Cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
1596 j(not_equal, fail); 1597 j(not_equal, fail);
1597 } 1598 }
1598 1599
1599 1600
1601 void MacroAssembler::AbortIfNotNumber(Register object, const char* msg) {
1602 Label ok;
1603 Condition is_smi = CheckSmi(object);
1604 j(is_smi, &ok);
1605 Cmp(FieldOperand(object, HeapObject::kMapOffset),
1606 Factory::heap_number_map());
1607 Assert(equal, msg);
1608 bind(&ok);
1609 }
1610
1611
1600 Condition MacroAssembler::IsObjectStringType(Register heap_object, 1612 Condition MacroAssembler::IsObjectStringType(Register heap_object,
1601 Register map, 1613 Register map,
1602 Register instance_type) { 1614 Register instance_type) {
1603 movq(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 1615 movq(map, FieldOperand(heap_object, HeapObject::kMapOffset));
1604 movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 1616 movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset));
1605 ASSERT(kNotStringTag != 0); 1617 ASSERT(kNotStringTag != 0);
1606 testb(instance_type, Immediate(kIsNotStringMask)); 1618 testb(instance_type, Immediate(kIsNotStringMask));
1607 return zero; 1619 return zero;
1608 } 1620 }
1609 1621
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 movq(scratch, Operand(base, 0)); 1779 movq(scratch, Operand(base, 0));
1768 ExternalReference reg_addr = 1780 ExternalReference reg_addr =
1769 ExternalReference(Debug_Address::Register(i)); 1781 ExternalReference(Debug_Address::Register(i));
1770 movq(kScratchRegister, reg_addr); 1782 movq(kScratchRegister, reg_addr);
1771 movq(Operand(kScratchRegister, 0), scratch); 1783 movq(Operand(kScratchRegister, 0), scratch);
1772 lea(base, Operand(base, kPointerSize)); 1784 lea(base, Operand(base, kPointerSize));
1773 } 1785 }
1774 } 1786 }
1775 } 1787 }
1776 1788
1789 void MacroAssembler::DebugBreak() {
1790 ASSERT(allow_stub_calls());
1791 xor_(rax, rax); // no arguments
1792 movq(rbx, ExternalReference(Runtime::kDebugBreak));
1793 CEntryStub ces(1);
1794 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
1795 }
1777 #endif // ENABLE_DEBUGGER_SUPPORT 1796 #endif // ENABLE_DEBUGGER_SUPPORT
1778 1797
1779 1798
1780 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
1781 bool resolved;
1782 Handle<Code> code = ResolveBuiltin(id, &resolved);
1783
1784 // Calls are not allowed in some stubs.
1785 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
1786
1787 // Rely on the assertion to check that the number of provided
1788 // arguments match the expected number of arguments. Fake a
1789 // parameter count to avoid emitting code to do the check.
1790 ParameterCount expected(0);
1791 InvokeCode(Handle<Code>(code),
1792 expected,
1793 expected,
1794 RelocInfo::CODE_TARGET,
1795 flag);
1796
1797 const char* name = Builtins::GetName(id);
1798 int argc = Builtins::GetArgumentsCount(id);
1799 // The target address for the jump is stored as an immediate at offset
1800 // kInvokeCodeAddressOffset.
1801 if (!resolved) {
1802 uint32_t flags =
1803 Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
1804 Bootstrapper::FixupFlagsUseCodeObject::encode(false);
1805 Unresolved entry =
1806 { pc_offset() - kCallTargetAddressOffset, flags, name };
1807 unresolved_.Add(entry);
1808 }
1809 }
1810
1811
1812 void MacroAssembler::InvokePrologue(const ParameterCount& expected, 1799 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
1813 const ParameterCount& actual, 1800 const ParameterCount& actual,
1814 Handle<Code> code_constant, 1801 Handle<Code> code_constant,
1815 Register code_register, 1802 Register code_register,
1816 Label* done, 1803 Label* done,
1817 InvokeFlag flag) { 1804 InvokeFlag flag) {
1818 bool definitely_matches = false; 1805 bool definitely_matches = false;
1819 Label invoke; 1806 Label invoke;
1820 if (expected.is_immediate()) { 1807 if (expected.is_immediate()) {
1821 ASSERT(actual.is_immediate()); 1808 ASSERT(actual.is_immediate());
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1919 movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset)); 1906 movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset));
1920 // Advances rdx to the end of the Code object header, to the start of 1907 // Advances rdx to the end of the Code object header, to the start of
1921 // the executable code. 1908 // the executable code.
1922 lea(rdx, FieldOperand(rdx, Code::kHeaderSize)); 1909 lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
1923 1910
1924 ParameterCount expected(rbx); 1911 ParameterCount expected(rbx);
1925 InvokeCode(rdx, expected, actual, flag); 1912 InvokeCode(rdx, expected, actual, flag);
1926 } 1913 }
1927 1914
1928 1915
1916 void MacroAssembler::InvokeFunction(JSFunction* function,
1917 const ParameterCount& actual,
1918 InvokeFlag flag) {
1919 ASSERT(function->is_compiled());
1920 // Get the function and setup the context.
1921 Move(rdi, Handle<JSFunction>(function));
1922 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
1923
1924 // Invoke the cached code.
1925 Handle<Code> code(function->code());
1926 ParameterCount expected(function->shared()->formal_parameter_count());
1927 InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
1928 }
1929
1930
1929 void MacroAssembler::EnterFrame(StackFrame::Type type) { 1931 void MacroAssembler::EnterFrame(StackFrame::Type type) {
1930 push(rbp); 1932 push(rbp);
1931 movq(rbp, rsp); 1933 movq(rbp, rsp);
1932 push(rsi); // Context. 1934 push(rsi); // Context.
1933 Push(Smi::FromInt(type)); 1935 Push(Smi::FromInt(type));
1934 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 1936 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
1935 push(kScratchRegister); 1937 push(kScratchRegister);
1936 if (FLAG_debug_code) { 1938 if (FLAG_debug_code) {
1937 movq(kScratchRegister, 1939 movq(kScratchRegister,
1938 Factory::undefined_value(), 1940 Factory::undefined_value(),
(...skipping 19 matching lines...) Expand all
1958 // Setup the frame structure on the stack. 1960 // Setup the frame structure on the stack.
1959 // All constants are relative to the frame pointer of the exit frame. 1961 // All constants are relative to the frame pointer of the exit frame.
1960 ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); 1962 ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize);
1961 ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); 1963 ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize);
1962 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); 1964 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize);
1963 push(rbp); 1965 push(rbp);
1964 movq(rbp, rsp); 1966 movq(rbp, rsp);
1965 1967
1966 // Reserve room for entry stack pointer and push the debug marker. 1968 // Reserve room for entry stack pointer and push the debug marker.
1967 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); 1969 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize);
1968 push(Immediate(0)); // saved entry sp, patched before call 1970 push(Immediate(0)); // Saved entry sp, patched before call.
1969 if (mode == ExitFrame::MODE_DEBUG) { 1971 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
1970 push(Immediate(0)); 1972 push(kScratchRegister); // Accessed from EditFrame::code_slot.
1971 } else {
1972 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
1973 push(kScratchRegister);
1974 }
1975 1973
1976 // Save the frame pointer and the context in top. 1974 // Save the frame pointer and the context in top.
1977 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); 1975 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
1978 ExternalReference context_address(Top::k_context_address); 1976 ExternalReference context_address(Top::k_context_address);
1979 movq(r14, rax); // Backup rax before we use it. 1977 movq(r14, rax); // Backup rax before we use it.
1980 1978
1981 movq(rax, rbp); 1979 movq(rax, rbp);
1982 store_rax(c_entry_fp_address); 1980 store_rax(c_entry_fp_address);
1983 movq(rax, rsi); 1981 movq(rax, rsi);
1984 store_rax(context_address); 1982 store_rax(context_address);
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
2579 CodePatcher::~CodePatcher() { 2577 CodePatcher::~CodePatcher() {
2580 // Indicate that code has changed. 2578 // Indicate that code has changed.
2581 CPU::FlushICache(address_, size_); 2579 CPU::FlushICache(address_, size_);
2582 2580
2583 // Check that the code was patched as expected. 2581 // Check that the code was patched as expected.
2584 ASSERT(masm_.pc_ == address_ + size_); 2582 ASSERT(masm_.pc_ == address_ + size_);
2585 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 2583 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
2586 } 2584 }
2587 2585
2588 } } // namespace v8::internal 2586 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698