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

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

Issue 7891042: Add asserts to ensure that we: (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 3 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/regexp-macro-assembler-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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 26 matching lines...) Expand all
37 #include "debug.h" 37 #include "debug.h"
38 #include "heap.h" 38 #include "heap.h"
39 39
40 namespace v8 { 40 namespace v8 {
41 namespace internal { 41 namespace internal {
42 42
43 MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) 43 MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size)
44 : Assembler(arg_isolate, buffer, size), 44 : Assembler(arg_isolate, buffer, size),
45 generating_stub_(false), 45 generating_stub_(false),
46 allow_stub_calls_(true), 46 allow_stub_calls_(true),
47 has_frame_(false),
47 root_array_available_(true) { 48 root_array_available_(true) {
48 if (isolate() != NULL) { 49 if (isolate() != NULL) {
49 code_object_ = Handle<Object>(isolate()->heap()->undefined_value(), 50 code_object_ = Handle<Object>(isolate()->heap()->undefined_value(),
50 isolate()); 51 isolate());
51 } 52 }
52 } 53 }
53 54
54 55
55 static intptr_t RootRegisterDelta(ExternalReference other, Isolate* isolate) { 56 static intptr_t RootRegisterDelta(ExternalReference other, Isolate* isolate) {
56 Address roots_register_value = kRootRegisterBias + 57 Address roots_register_value = kRootRegisterBias +
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 Abort("JSObject with fast elements map has slow elements"); 394 Abort("JSObject with fast elements map has slow elements");
394 bind(&ok); 395 bind(&ok);
395 } 396 }
396 } 397 }
397 398
398 399
399 void MacroAssembler::Check(Condition cc, const char* msg) { 400 void MacroAssembler::Check(Condition cc, const char* msg) {
400 Label L; 401 Label L;
401 j(cc, &L, Label::kNear); 402 j(cc, &L, Label::kNear);
402 Abort(msg); 403 Abort(msg);
403 // will not return here 404 // Control will not return here.
404 bind(&L); 405 bind(&L);
405 } 406 }
406 407
407 408
408 void MacroAssembler::CheckStackAlignment() { 409 void MacroAssembler::CheckStackAlignment() {
409 int frame_alignment = OS::ActivationFrameAlignment(); 410 int frame_alignment = OS::ActivationFrameAlignment();
410 int frame_alignment_mask = frame_alignment - 1; 411 int frame_alignment_mask = frame_alignment - 1;
411 if (frame_alignment > kPointerSize) { 412 if (frame_alignment > kPointerSize) {
412 ASSERT(IsPowerOf2(frame_alignment)); 413 ASSERT(IsPowerOf2(frame_alignment));
413 Label alignment_as_expected; 414 Label alignment_as_expected;
(...skipping 27 matching lines...) Expand all
441 intptr_t p1 = reinterpret_cast<intptr_t>(msg); 442 intptr_t p1 = reinterpret_cast<intptr_t>(msg);
442 intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag; 443 intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag;
443 // Note: p0 might not be a valid Smi *value*, but it has a valid Smi tag. 444 // Note: p0 might not be a valid Smi *value*, but it has a valid Smi tag.
444 ASSERT(reinterpret_cast<Object*>(p0)->IsSmi()); 445 ASSERT(reinterpret_cast<Object*>(p0)->IsSmi());
445 #ifdef DEBUG 446 #ifdef DEBUG
446 if (msg != NULL) { 447 if (msg != NULL) {
447 RecordComment("Abort message: "); 448 RecordComment("Abort message: ");
448 RecordComment(msg); 449 RecordComment(msg);
449 } 450 }
450 #endif 451 #endif
451 // Disable stub call restrictions to always allow calls to abort.
452 AllowStubCallsScope allow_scope(this, true);
453
454 push(rax); 452 push(rax);
455 movq(kScratchRegister, p0, RelocInfo::NONE); 453 movq(kScratchRegister, p0, RelocInfo::NONE);
456 push(kScratchRegister); 454 push(kScratchRegister);
457 movq(kScratchRegister, 455 movq(kScratchRegister,
458 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(p1 - p0))), 456 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(p1 - p0))),
459 RelocInfo::NONE); 457 RelocInfo::NONE);
460 push(kScratchRegister); 458 push(kScratchRegister);
461 CallRuntime(Runtime::kAbort, 2); 459
462 // will not return here 460 if (!has_frame_) {
461 // We don't actually want to generate a pile of code for this, so just
462 // claim there is a stack frame, without generating one.
463 FrameScope scope(this, StackFrame::NONE);
464 CallRuntime(Runtime::kAbort, 2);
465 } else {
466 CallRuntime(Runtime::kAbort, 2);
467 }
468 // Control will not return here.
463 int3(); 469 int3();
464 } 470 }
465 471
466 472
467 void MacroAssembler::CallStub(CodeStub* stub, unsigned ast_id) { 473 void MacroAssembler::CallStub(CodeStub* stub, unsigned ast_id) {
468 ASSERT(allow_stub_calls()); // calls are not allowed in some stubs 474 ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs
469 Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id); 475 Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
470 } 476 }
471 477
472 478
473 MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub) { 479 MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub) {
474 ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs. 480 ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs.
475 MaybeObject* result = stub->TryGetCode(); 481 MaybeObject* result = stub->TryGetCode();
476 if (!result->IsFailure()) { 482 if (!result->IsFailure()) {
477 call(Handle<Code>(Code::cast(result->ToObjectUnchecked())), 483 call(Handle<Code>(Code::cast(result->ToObjectUnchecked())),
478 RelocInfo::CODE_TARGET); 484 RelocInfo::CODE_TARGET);
479 } 485 }
480 return result; 486 return result;
481 } 487 }
482 488
483 489
484 void MacroAssembler::TailCallStub(CodeStub* stub) { 490 void MacroAssembler::TailCallStub(CodeStub* stub) {
485 ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs. 491 ASSERT(stub->CompilingCallsToThisStubIsGCSafe() || allow_stub_calls_);
486 Jump(stub->GetCode(), RelocInfo::CODE_TARGET); 492 Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
487 } 493 }
488 494
489 495
490 MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub) { 496 MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub) {
491 ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
492 MaybeObject* result = stub->TryGetCode(); 497 MaybeObject* result = stub->TryGetCode();
493 if (!result->IsFailure()) { 498 if (!result->IsFailure()) {
494 jmp(Handle<Code>(Code::cast(result->ToObjectUnchecked())), 499 jmp(Handle<Code>(Code::cast(result->ToObjectUnchecked())),
495 RelocInfo::CODE_TARGET); 500 RelocInfo::CODE_TARGET);
496 } 501 }
497 return result; 502 return result;
498 } 503 }
499 504
500 505
501 void MacroAssembler::StubReturn(int argc) { 506 void MacroAssembler::StubReturn(int argc) {
502 ASSERT(argc >= 1 && generating_stub()); 507 ASSERT(argc >= 1 && generating_stub());
503 ret((argc - 1) * kPointerSize); 508 ret((argc - 1) * kPointerSize);
504 } 509 }
505 510
506 511
512 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
513 if (!has_frame_ && stub->SometimesSetsUpAFrame()) return false;
514 return stub->CompilingCallsToThisStubIsGCSafe() || allow_stub_calls_;
515 }
516
517
507 void MacroAssembler::IllegalOperation(int num_arguments) { 518 void MacroAssembler::IllegalOperation(int num_arguments) {
508 if (num_arguments > 0) { 519 if (num_arguments > 0) {
509 addq(rsp, Immediate(num_arguments * kPointerSize)); 520 addq(rsp, Immediate(num_arguments * kPointerSize));
510 } 521 }
511 LoadRoot(rax, Heap::kUndefinedValueRootIndex); 522 LoadRoot(rax, Heap::kUndefinedValueRootIndex);
512 } 523 }
513 524
514 525
515 void MacroAssembler::IndexFromHash(Register hash, Register index) { 526 void MacroAssembler::IndexFromHash(Register hash, Register index) {
516 // The assert checks that the constants for the maximum number of digits 527 // The assert checks that the constants for the maximum number of digits
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 // Set the entry point and jump to the C entry runtime stub. 799 // Set the entry point and jump to the C entry runtime stub.
789 LoadAddress(rbx, ext); 800 LoadAddress(rbx, ext);
790 CEntryStub ces(result_size); 801 CEntryStub ces(result_size);
791 return TryTailCallStub(&ces); 802 return TryTailCallStub(&ces);
792 } 803 }
793 804
794 805
795 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, 806 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
796 InvokeFlag flag, 807 InvokeFlag flag,
797 const CallWrapper& call_wrapper) { 808 const CallWrapper& call_wrapper) {
798 // Calls are not allowed in some stubs. 809 // You can't call a builtin without a valid frame.
799 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); 810 ASSERT(flag == JUMP_FUNCTION || has_frame());
800 811
801 // Rely on the assertion to check that the number of provided 812 // Rely on the assertion to check that the number of provided
802 // arguments match the expected number of arguments. Fake a 813 // arguments match the expected number of arguments. Fake a
803 // parameter count to avoid emitting code to do the check. 814 // parameter count to avoid emitting code to do the check.
804 ParameterCount expected(0); 815 ParameterCount expected(0);
805 GetBuiltinEntry(rdx, id); 816 GetBuiltinEntry(rdx, id);
806 InvokeCode(rdx, expected, expected, flag, call_wrapper, CALL_AS_METHOD); 817 InvokeCode(rdx, expected, expected, flag, call_wrapper, CALL_AS_METHOD);
807 } 818 }
808 819
809 820
(...skipping 1970 matching lines...) Expand 10 before | Expand all | Expand 10 after
2780 decl(counter_operand); 2791 decl(counter_operand);
2781 } else { 2792 } else {
2782 subl(counter_operand, Immediate(value)); 2793 subl(counter_operand, Immediate(value));
2783 } 2794 }
2784 } 2795 }
2785 } 2796 }
2786 2797
2787 2798
2788 #ifdef ENABLE_DEBUGGER_SUPPORT 2799 #ifdef ENABLE_DEBUGGER_SUPPORT
2789 void MacroAssembler::DebugBreak() { 2800 void MacroAssembler::DebugBreak() {
2790 ASSERT(allow_stub_calls());
2791 Set(rax, 0); // No arguments. 2801 Set(rax, 0); // No arguments.
2792 LoadAddress(rbx, ExternalReference(Runtime::kDebugBreak, isolate())); 2802 LoadAddress(rbx, ExternalReference(Runtime::kDebugBreak, isolate()));
2793 CEntryStub ces(1); 2803 CEntryStub ces(1);
2804 ASSERT(AllowThisStubCall(&ces));
2794 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); 2805 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
2795 } 2806 }
2796 #endif // ENABLE_DEBUGGER_SUPPORT 2807 #endif // ENABLE_DEBUGGER_SUPPORT
2797 2808
2798 2809
2799 void MacroAssembler::SetCallKind(Register dst, CallKind call_kind) { 2810 void MacroAssembler::SetCallKind(Register dst, CallKind call_kind) {
2800 // This macro takes the dst register to make the code more readable 2811 // This macro takes the dst register to make the code more readable
2801 // at the call sites. However, the dst register has to be rcx to 2812 // at the call sites. However, the dst register has to be rcx to
2802 // follow the calling convention which requires the call type to be 2813 // follow the calling convention which requires the call type to be
2803 // in rcx. 2814 // in rcx.
2804 ASSERT(dst.is(rcx)); 2815 ASSERT(dst.is(rcx));
2805 if (call_kind == CALL_AS_FUNCTION) { 2816 if (call_kind == CALL_AS_FUNCTION) {
2806 LoadSmiConstant(dst, Smi::FromInt(1)); 2817 LoadSmiConstant(dst, Smi::FromInt(1));
2807 } else { 2818 } else {
2808 LoadSmiConstant(dst, Smi::FromInt(0)); 2819 LoadSmiConstant(dst, Smi::FromInt(0));
2809 } 2820 }
2810 } 2821 }
2811 2822
2812 2823
2813 void MacroAssembler::InvokeCode(Register code, 2824 void MacroAssembler::InvokeCode(Register code,
2814 const ParameterCount& expected, 2825 const ParameterCount& expected,
2815 const ParameterCount& actual, 2826 const ParameterCount& actual,
2816 InvokeFlag flag, 2827 InvokeFlag flag,
2817 const CallWrapper& call_wrapper, 2828 const CallWrapper& call_wrapper,
2818 CallKind call_kind) { 2829 CallKind call_kind) {
2830 // You can't call a function without a valid frame.
2831 ASSERT(flag == JUMP_FUNCTION || has_frame());
2832
2819 Label done; 2833 Label done;
2820 InvokePrologue(expected, 2834 InvokePrologue(expected,
2821 actual, 2835 actual,
2822 Handle<Code>::null(), 2836 Handle<Code>::null(),
2823 code, 2837 code,
2824 &done, 2838 &done,
2825 flag, 2839 flag,
2826 Label::kNear, 2840 Label::kNear,
2827 call_wrapper, 2841 call_wrapper,
2828 call_kind); 2842 call_kind);
(...skipping 11 matching lines...) Expand all
2840 } 2854 }
2841 2855
2842 2856
2843 void MacroAssembler::InvokeCode(Handle<Code> code, 2857 void MacroAssembler::InvokeCode(Handle<Code> code,
2844 const ParameterCount& expected, 2858 const ParameterCount& expected,
2845 const ParameterCount& actual, 2859 const ParameterCount& actual,
2846 RelocInfo::Mode rmode, 2860 RelocInfo::Mode rmode,
2847 InvokeFlag flag, 2861 InvokeFlag flag,
2848 const CallWrapper& call_wrapper, 2862 const CallWrapper& call_wrapper,
2849 CallKind call_kind) { 2863 CallKind call_kind) {
2864 // You can't call a function without a valid frame.
2865 ASSERT(flag == JUMP_FUNCTION || has_frame());
2866
2850 Label done; 2867 Label done;
2851 Register dummy = rax; 2868 Register dummy = rax;
2852 InvokePrologue(expected, 2869 InvokePrologue(expected,
2853 actual, 2870 actual,
2854 code, 2871 code,
2855 dummy, 2872 dummy,
2856 &done, 2873 &done,
2857 flag, 2874 flag,
2858 Label::kNear, 2875 Label::kNear,
2859 call_wrapper, 2876 call_wrapper,
(...skipping 10 matching lines...) Expand all
2870 } 2887 }
2871 bind(&done); 2888 bind(&done);
2872 } 2889 }
2873 2890
2874 2891
2875 void MacroAssembler::InvokeFunction(Register function, 2892 void MacroAssembler::InvokeFunction(Register function,
2876 const ParameterCount& actual, 2893 const ParameterCount& actual,
2877 InvokeFlag flag, 2894 InvokeFlag flag,
2878 const CallWrapper& call_wrapper, 2895 const CallWrapper& call_wrapper,
2879 CallKind call_kind) { 2896 CallKind call_kind) {
2897 // You can't call a function without a valid frame.
2898 ASSERT(flag == JUMP_FUNCTION || has_frame());
2899
2880 ASSERT(function.is(rdi)); 2900 ASSERT(function.is(rdi));
2881 movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 2901 movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
2882 movq(rsi, FieldOperand(function, JSFunction::kContextOffset)); 2902 movq(rsi, FieldOperand(function, JSFunction::kContextOffset));
2883 movsxlq(rbx, 2903 movsxlq(rbx,
2884 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); 2904 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset));
2885 // Advances rdx to the end of the Code object header, to the start of 2905 // Advances rdx to the end of the Code object header, to the start of
2886 // the executable code. 2906 // the executable code.
2887 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2907 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2888 2908
2889 ParameterCount expected(rbx); 2909 ParameterCount expected(rbx);
2890 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind); 2910 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind);
2891 } 2911 }
2892 2912
2893 2913
2894 void MacroAssembler::InvokeFunction(JSFunction* function, 2914 void MacroAssembler::InvokeFunction(JSFunction* function,
2895 const ParameterCount& actual, 2915 const ParameterCount& actual,
2896 InvokeFlag flag, 2916 InvokeFlag flag,
2897 const CallWrapper& call_wrapper, 2917 const CallWrapper& call_wrapper,
2898 CallKind call_kind) { 2918 CallKind call_kind) {
2919 // You can't call a function without a valid frame.
2920 ASSERT(flag == JUMP_FUNCTION || has_frame());
2921
2899 ASSERT(function->is_compiled()); 2922 ASSERT(function->is_compiled());
2900 // Get the function and setup the context. 2923 // Get the function and setup the context.
2901 Move(rdi, Handle<JSFunction>(function)); 2924 Move(rdi, Handle<JSFunction>(function));
2902 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 2925 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
2903 2926
2904 if (V8::UseCrankshaft()) { 2927 if (V8::UseCrankshaft()) {
2905 // Since Crankshaft can recompile a function, we need to load 2928 // Since Crankshaft can recompile a function, we need to load
2906 // the Code object every time we call the function. 2929 // the Code object every time we call the function.
2907 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2930 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2908 ParameterCount expected(function->shared()->formal_parameter_count()); 2931 ParameterCount expected(function->shared()->formal_parameter_count());
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after
3851 3874
3852 3875
3853 void MacroAssembler::CallCFunction(ExternalReference function, 3876 void MacroAssembler::CallCFunction(ExternalReference function,
3854 int num_arguments) { 3877 int num_arguments) {
3855 LoadAddress(rax, function); 3878 LoadAddress(rax, function);
3856 CallCFunction(rax, num_arguments); 3879 CallCFunction(rax, num_arguments);
3857 } 3880 }
3858 3881
3859 3882
3860 void MacroAssembler::CallCFunction(Register function, int num_arguments) { 3883 void MacroAssembler::CallCFunction(Register function, int num_arguments) {
3884 ASSERT(has_frame());
3861 // Check stack alignment. 3885 // Check stack alignment.
3862 if (emit_debug_code()) { 3886 if (emit_debug_code()) {
3863 CheckStackAlignment(); 3887 CheckStackAlignment();
3864 } 3888 }
3865 3889
3866 call(function); 3890 call(function);
3867 ASSERT(OS::ActivationFrameAlignment() != 0); 3891 ASSERT(OS::ActivationFrameAlignment() != 0);
3868 ASSERT(num_arguments >= 0); 3892 ASSERT(num_arguments >= 0);
3869 int argument_slots_on_stack = 3893 int argument_slots_on_stack =
3870 ArgumentStackSlotsForCFunctionCall(num_arguments); 3894 ArgumentStackSlotsForCFunctionCall(num_arguments);
(...skipping 17 matching lines...) Expand all
3888 CPU::FlushICache(address_, size_); 3912 CPU::FlushICache(address_, size_);
3889 3913
3890 // Check that the code was patched as expected. 3914 // Check that the code was patched as expected.
3891 ASSERT(masm_.pc_ == address_ + size_); 3915 ASSERT(masm_.pc_ == address_ + size_);
3892 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 3916 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
3893 } 3917 }
3894 3918
3895 } } // namespace v8::internal 3919 } } // namespace v8::internal
3896 3920
3897 #endif // V8_TARGET_ARCH_X64 3921 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/regexp-macro-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698