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

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

Issue 7084032: Add asserts and state tracking to ensure that we do not call (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 6 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 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 Abort("JSObject with fast elements map has slow elements"); 391 Abort("JSObject with fast elements map has slow elements");
391 bind(&ok); 392 bind(&ok);
392 } 393 }
393 } 394 }
394 395
395 396
396 void MacroAssembler::Check(Condition cc, const char* msg) { 397 void MacroAssembler::Check(Condition cc, const char* msg) {
397 Label L; 398 Label L;
398 j(cc, &L, Label::kNear); 399 j(cc, &L, Label::kNear);
399 Abort(msg); 400 Abort(msg);
400 // will not return here 401 // Control will not return here.
401 bind(&L); 402 bind(&L);
402 } 403 }
403 404
404 405
405 void MacroAssembler::CheckStackAlignment() { 406 void MacroAssembler::CheckStackAlignment() {
406 int frame_alignment = OS::ActivationFrameAlignment(); 407 int frame_alignment = OS::ActivationFrameAlignment();
407 int frame_alignment_mask = frame_alignment - 1; 408 int frame_alignment_mask = frame_alignment - 1;
408 if (frame_alignment > kPointerSize) { 409 if (frame_alignment > kPointerSize) {
409 ASSERT(IsPowerOf2(frame_alignment)); 410 ASSERT(IsPowerOf2(frame_alignment));
410 Label alignment_as_expected; 411 Label alignment_as_expected;
(...skipping 27 matching lines...) Expand all
438 intptr_t p1 = reinterpret_cast<intptr_t>(msg); 439 intptr_t p1 = reinterpret_cast<intptr_t>(msg);
439 intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag; 440 intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag;
440 // Note: p0 might not be a valid Smi *value*, but it has a valid Smi tag. 441 // Note: p0 might not be a valid Smi *value*, but it has a valid Smi tag.
441 ASSERT(reinterpret_cast<Object*>(p0)->IsSmi()); 442 ASSERT(reinterpret_cast<Object*>(p0)->IsSmi());
442 #ifdef DEBUG 443 #ifdef DEBUG
443 if (msg != NULL) { 444 if (msg != NULL) {
444 RecordComment("Abort message: "); 445 RecordComment("Abort message: ");
445 RecordComment(msg); 446 RecordComment(msg);
446 } 447 }
447 #endif 448 #endif
448 // Disable stub call restrictions to always allow calls to abort.
449 AllowStubCallsScope allow_scope(this, true);
450
451 push(rax); 449 push(rax);
452 movq(kScratchRegister, p0, RelocInfo::NONE); 450 movq(kScratchRegister, p0, RelocInfo::NONE);
453 push(kScratchRegister); 451 push(kScratchRegister);
454 movq(kScratchRegister, 452 movq(kScratchRegister,
455 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(p1 - p0))), 453 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(p1 - p0))),
456 RelocInfo::NONE); 454 RelocInfo::NONE);
457 push(kScratchRegister); 455 push(kScratchRegister);
458 CallRuntime(Runtime::kAbort, 2); 456
459 // will not return here 457 if (!has_frame_) {
458 // We don't actually want to generate a pile of code for this, so just
459 // claim there is a stack frame, without generating one.
460 FrameScope scope(this, StackFrame::NONE);
461 CallRuntime(Runtime::kAbort, 2);
462 } else {
463 CallRuntime(Runtime::kAbort, 2);
464 }
465 // Control will not return here.
460 int3(); 466 int3();
461 } 467 }
462 468
463 469
464 void MacroAssembler::CallStub(CodeStub* stub, unsigned ast_id) { 470 void MacroAssembler::CallStub(CodeStub* stub, unsigned ast_id) {
465 ASSERT(allow_stub_calls()); // calls are not allowed in some stubs 471 ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs
466 Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id); 472 Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
467 } 473 }
468 474
469 475
470 MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub) { 476 MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub) {
471 ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs. 477 ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs.
472 MaybeObject* result = stub->TryGetCode(); 478 MaybeObject* result = stub->TryGetCode();
473 if (!result->IsFailure()) { 479 if (!result->IsFailure()) {
474 call(Handle<Code>(Code::cast(result->ToObjectUnchecked())), 480 call(Handle<Code>(Code::cast(result->ToObjectUnchecked())),
475 RelocInfo::CODE_TARGET); 481 RelocInfo::CODE_TARGET);
476 } 482 }
477 return result; 483 return result;
478 } 484 }
479 485
480 486
481 void MacroAssembler::TailCallStub(CodeStub* stub) { 487 void MacroAssembler::TailCallStub(CodeStub* stub) {
482 ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs. 488 ASSERT(stub->CompilingCallsToThisStubIsGCSafe() || allow_stub_calls_);
483 Jump(stub->GetCode(), RelocInfo::CODE_TARGET); 489 Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
484 } 490 }
485 491
486 492
487 MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub) { 493 MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub) {
488 ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
489 MaybeObject* result = stub->TryGetCode(); 494 MaybeObject* result = stub->TryGetCode();
490 if (!result->IsFailure()) { 495 if (!result->IsFailure()) {
491 jmp(Handle<Code>(Code::cast(result->ToObjectUnchecked())), 496 jmp(Handle<Code>(Code::cast(result->ToObjectUnchecked())),
492 RelocInfo::CODE_TARGET); 497 RelocInfo::CODE_TARGET);
493 } 498 }
494 return result; 499 return result;
495 } 500 }
496 501
497 502
498 void MacroAssembler::StubReturn(int argc) { 503 void MacroAssembler::StubReturn(int argc) {
499 ASSERT(argc >= 1 && generating_stub()); 504 ASSERT(argc >= 1 && generating_stub());
500 ret((argc - 1) * kPointerSize); 505 ret((argc - 1) * kPointerSize);
501 } 506 }
502 507
503 508
509 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
510 if (!has_frame_ && stub->SometimesSetsUpAFrame()) return false;
511 return stub->CompilingCallsToThisStubIsGCSafe() || allow_stub_calls_;
512 }
513
514
504 void MacroAssembler::IllegalOperation(int num_arguments) { 515 void MacroAssembler::IllegalOperation(int num_arguments) {
505 if (num_arguments > 0) { 516 if (num_arguments > 0) {
506 addq(rsp, Immediate(num_arguments * kPointerSize)); 517 addq(rsp, Immediate(num_arguments * kPointerSize));
507 } 518 }
508 LoadRoot(rax, Heap::kUndefinedValueRootIndex); 519 LoadRoot(rax, Heap::kUndefinedValueRootIndex);
509 } 520 }
510 521
511 522
512 void MacroAssembler::IndexFromHash(Register hash, Register index) { 523 void MacroAssembler::IndexFromHash(Register hash, Register index) {
513 // The assert checks that the constants for the maximum number of digits 524 // The assert checks that the constants for the maximum number of digits
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 // Set the entry point and jump to the C entry runtime stub. 796 // Set the entry point and jump to the C entry runtime stub.
786 LoadAddress(rbx, ext); 797 LoadAddress(rbx, ext);
787 CEntryStub ces(result_size); 798 CEntryStub ces(result_size);
788 return TryTailCallStub(&ces); 799 return TryTailCallStub(&ces);
789 } 800 }
790 801
791 802
792 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, 803 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
793 InvokeFlag flag, 804 InvokeFlag flag,
794 const CallWrapper& call_wrapper) { 805 const CallWrapper& call_wrapper) {
795 // Calls are not allowed in some stubs. 806 // You can't call a builtin without a valid frame.
796 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); 807 ASSERT(flag == JUMP_FUNCTION || has_frame());
797 808
798 // Rely on the assertion to check that the number of provided 809 // Rely on the assertion to check that the number of provided
799 // arguments match the expected number of arguments. Fake a 810 // arguments match the expected number of arguments. Fake a
800 // parameter count to avoid emitting code to do the check. 811 // parameter count to avoid emitting code to do the check.
801 ParameterCount expected(0); 812 ParameterCount expected(0);
802 GetBuiltinEntry(rdx, id); 813 GetBuiltinEntry(rdx, id);
803 InvokeCode(rdx, expected, expected, flag, call_wrapper, CALL_AS_METHOD); 814 InvokeCode(rdx, expected, expected, flag, call_wrapper, CALL_AS_METHOD);
804 } 815 }
805 816
806 817
(...skipping 1957 matching lines...) Expand 10 before | Expand all | Expand 10 after
2764 decl(counter_operand); 2775 decl(counter_operand);
2765 } else { 2776 } else {
2766 subl(counter_operand, Immediate(value)); 2777 subl(counter_operand, Immediate(value));
2767 } 2778 }
2768 } 2779 }
2769 } 2780 }
2770 2781
2771 2782
2772 #ifdef ENABLE_DEBUGGER_SUPPORT 2783 #ifdef ENABLE_DEBUGGER_SUPPORT
2773 void MacroAssembler::DebugBreak() { 2784 void MacroAssembler::DebugBreak() {
2774 ASSERT(allow_stub_calls());
2775 Set(rax, 0); // No arguments. 2785 Set(rax, 0); // No arguments.
2776 LoadAddress(rbx, ExternalReference(Runtime::kDebugBreak, isolate())); 2786 LoadAddress(rbx, ExternalReference(Runtime::kDebugBreak, isolate()));
2777 CEntryStub ces(1); 2787 CEntryStub ces(1);
2788 ASSERT(AllowThisStubCall(&ces));
2778 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); 2789 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
2779 } 2790 }
2780 #endif // ENABLE_DEBUGGER_SUPPORT 2791 #endif // ENABLE_DEBUGGER_SUPPORT
2781 2792
2782 2793
2783 void MacroAssembler::SetCallKind(Register dst, CallKind call_kind) { 2794 void MacroAssembler::SetCallKind(Register dst, CallKind call_kind) {
2784 // This macro takes the dst register to make the code more readable 2795 // This macro takes the dst register to make the code more readable
2785 // at the call sites. However, the dst register has to be rcx to 2796 // at the call sites. However, the dst register has to be rcx to
2786 // follow the calling convention which requires the call type to be 2797 // follow the calling convention which requires the call type to be
2787 // in rcx. 2798 // in rcx.
2788 ASSERT(dst.is(rcx)); 2799 ASSERT(dst.is(rcx));
2789 if (call_kind == CALL_AS_FUNCTION) { 2800 if (call_kind == CALL_AS_FUNCTION) {
2790 LoadSmiConstant(dst, Smi::FromInt(1)); 2801 LoadSmiConstant(dst, Smi::FromInt(1));
2791 } else { 2802 } else {
2792 LoadSmiConstant(dst, Smi::FromInt(0)); 2803 LoadSmiConstant(dst, Smi::FromInt(0));
2793 } 2804 }
2794 } 2805 }
2795 2806
2796 2807
2797 void MacroAssembler::InvokeCode(Register code, 2808 void MacroAssembler::InvokeCode(Register code,
2798 const ParameterCount& expected, 2809 const ParameterCount& expected,
2799 const ParameterCount& actual, 2810 const ParameterCount& actual,
2800 InvokeFlag flag, 2811 InvokeFlag flag,
2801 const CallWrapper& call_wrapper, 2812 const CallWrapper& call_wrapper,
2802 CallKind call_kind) { 2813 CallKind call_kind) {
2814 // You can't call a function without a valid frame.
2815 ASSERT(flag == JUMP_FUNCTION || has_frame());
2816
2803 Label done; 2817 Label done;
2804 InvokePrologue(expected, 2818 InvokePrologue(expected,
2805 actual, 2819 actual,
2806 Handle<Code>::null(), 2820 Handle<Code>::null(),
2807 code, 2821 code,
2808 &done, 2822 &done,
2809 flag, 2823 flag,
2810 Label::kNear, 2824 Label::kNear,
2811 call_wrapper, 2825 call_wrapper,
2812 call_kind); 2826 call_kind);
(...skipping 11 matching lines...) Expand all
2824 } 2838 }
2825 2839
2826 2840
2827 void MacroAssembler::InvokeCode(Handle<Code> code, 2841 void MacroAssembler::InvokeCode(Handle<Code> code,
2828 const ParameterCount& expected, 2842 const ParameterCount& expected,
2829 const ParameterCount& actual, 2843 const ParameterCount& actual,
2830 RelocInfo::Mode rmode, 2844 RelocInfo::Mode rmode,
2831 InvokeFlag flag, 2845 InvokeFlag flag,
2832 const CallWrapper& call_wrapper, 2846 const CallWrapper& call_wrapper,
2833 CallKind call_kind) { 2847 CallKind call_kind) {
2848 // You can't call a function without a valid frame.
2849 ASSERT(flag == JUMP_FUNCTION || has_frame());
2850
2834 Label done; 2851 Label done;
2835 Register dummy = rax; 2852 Register dummy = rax;
2836 InvokePrologue(expected, 2853 InvokePrologue(expected,
2837 actual, 2854 actual,
2838 code, 2855 code,
2839 dummy, 2856 dummy,
2840 &done, 2857 &done,
2841 flag, 2858 flag,
2842 Label::kNear, 2859 Label::kNear,
2843 call_wrapper, 2860 call_wrapper,
(...skipping 10 matching lines...) Expand all
2854 } 2871 }
2855 bind(&done); 2872 bind(&done);
2856 } 2873 }
2857 2874
2858 2875
2859 void MacroAssembler::InvokeFunction(Register function, 2876 void MacroAssembler::InvokeFunction(Register function,
2860 const ParameterCount& actual, 2877 const ParameterCount& actual,
2861 InvokeFlag flag, 2878 InvokeFlag flag,
2862 const CallWrapper& call_wrapper, 2879 const CallWrapper& call_wrapper,
2863 CallKind call_kind) { 2880 CallKind call_kind) {
2881 // You can't call a function without a valid frame.
2882 ASSERT(flag == JUMP_FUNCTION || has_frame());
2883
2864 ASSERT(function.is(rdi)); 2884 ASSERT(function.is(rdi));
2865 movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 2885 movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
2866 movq(rsi, FieldOperand(function, JSFunction::kContextOffset)); 2886 movq(rsi, FieldOperand(function, JSFunction::kContextOffset));
2867 movsxlq(rbx, 2887 movsxlq(rbx,
2868 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); 2888 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset));
2869 // Advances rdx to the end of the Code object header, to the start of 2889 // Advances rdx to the end of the Code object header, to the start of
2870 // the executable code. 2890 // the executable code.
2871 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2891 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2872 2892
2873 ParameterCount expected(rbx); 2893 ParameterCount expected(rbx);
2874 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind); 2894 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind);
2875 } 2895 }
2876 2896
2877 2897
2878 void MacroAssembler::InvokeFunction(JSFunction* function, 2898 void MacroAssembler::InvokeFunction(JSFunction* function,
2879 const ParameterCount& actual, 2899 const ParameterCount& actual,
2880 InvokeFlag flag, 2900 InvokeFlag flag,
2881 const CallWrapper& call_wrapper, 2901 const CallWrapper& call_wrapper,
2882 CallKind call_kind) { 2902 CallKind call_kind) {
2903 // You can't call a function without a valid frame.
2904 ASSERT(flag == JUMP_FUNCTION || has_frame());
2905
2883 ASSERT(function->is_compiled()); 2906 ASSERT(function->is_compiled());
2884 // Get the function and setup the context. 2907 // Get the function and setup the context.
2885 Move(rdi, Handle<JSFunction>(function)); 2908 Move(rdi, Handle<JSFunction>(function));
2886 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 2909 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
2887 2910
2888 if (V8::UseCrankshaft()) { 2911 if (V8::UseCrankshaft()) {
2889 // Since Crankshaft can recompile a function, we need to load 2912 // Since Crankshaft can recompile a function, we need to load
2890 // the Code object every time we call the function. 2913 // the Code object every time we call the function.
2891 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2914 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2892 ParameterCount expected(function->shared()->formal_parameter_count()); 2915 ParameterCount expected(function->shared()->formal_parameter_count());
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after
3701 3724
3702 3725
3703 void MacroAssembler::CallCFunction(ExternalReference function, 3726 void MacroAssembler::CallCFunction(ExternalReference function,
3704 int num_arguments) { 3727 int num_arguments) {
3705 LoadAddress(rax, function); 3728 LoadAddress(rax, function);
3706 CallCFunction(rax, num_arguments); 3729 CallCFunction(rax, num_arguments);
3707 } 3730 }
3708 3731
3709 3732
3710 void MacroAssembler::CallCFunction(Register function, int num_arguments) { 3733 void MacroAssembler::CallCFunction(Register function, int num_arguments) {
3734 ASSERT(has_frame());
3711 // Check stack alignment. 3735 // Check stack alignment.
3712 if (emit_debug_code()) { 3736 if (emit_debug_code()) {
3713 CheckStackAlignment(); 3737 CheckStackAlignment();
3714 } 3738 }
3715 3739
3716 call(function); 3740 call(function);
3717 ASSERT(OS::ActivationFrameAlignment() != 0); 3741 ASSERT(OS::ActivationFrameAlignment() != 0);
3718 ASSERT(num_arguments >= 0); 3742 ASSERT(num_arguments >= 0);
3719 int argument_slots_on_stack = 3743 int argument_slots_on_stack =
3720 ArgumentStackSlotsForCFunctionCall(num_arguments); 3744 ArgumentStackSlotsForCFunctionCall(num_arguments);
(...skipping 17 matching lines...) Expand all
3738 CPU::FlushICache(address_, size_); 3762 CPU::FlushICache(address_, size_);
3739 3763
3740 // Check that the code was patched as expected. 3764 // Check that the code was patched as expected.
3741 ASSERT(masm_.pc_ == address_ + size_); 3765 ASSERT(masm_.pc_ == address_ + size_);
3742 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 3766 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
3743 } 3767 }
3744 3768
3745 } } // namespace v8::internal 3769 } } // namespace v8::internal
3746 3770
3747 #endif // V8_TARGET_ARCH_X64 3771 #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