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

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

Issue 185653004: Experimental parser: merge to r19637 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 } 156 }
157 // Size of movp(destination, src); 157 // Size of movp(destination, src);
158 return Assembler::kMoveAddressIntoScratchRegisterInstructionLength; 158 return Assembler::kMoveAddressIntoScratchRegisterInstructionLength;
159 } 159 }
160 160
161 161
162 void MacroAssembler::PushAddress(ExternalReference source) { 162 void MacroAssembler::PushAddress(ExternalReference source) {
163 int64_t address = reinterpret_cast<int64_t>(source.address()); 163 int64_t address = reinterpret_cast<int64_t>(source.address());
164 if (is_int32(address) && !Serializer::enabled()) { 164 if (is_int32(address) && !Serializer::enabled()) {
165 if (emit_debug_code()) { 165 if (emit_debug_code()) {
166 Move(kScratchRegister, kZapValue, RelocInfo::NONE64); 166 Move(kScratchRegister, kZapValue, Assembler::RelocInfoNone());
167 } 167 }
168 push(Immediate(static_cast<int32_t>(address))); 168 push(Immediate(static_cast<int32_t>(address)));
169 return; 169 return;
170 } 170 }
171 LoadAddress(kScratchRegister, source); 171 LoadAddress(kScratchRegister, source);
172 push(kScratchRegister); 172 push(kScratchRegister);
173 } 173 }
174 174
175 175
176 void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) { 176 void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 and_(scratch, object); 282 and_(scratch, object);
283 } 283 }
284 Move(kScratchRegister, ExternalReference::new_space_start(isolate())); 284 Move(kScratchRegister, ExternalReference::new_space_start(isolate()));
285 cmpq(scratch, kScratchRegister); 285 cmpq(scratch, kScratchRegister);
286 j(cc, branch, distance); 286 j(cc, branch, distance);
287 } else { 287 } else {
288 ASSERT(is_int32(static_cast<int64_t>(isolate()->heap()->NewSpaceMask()))); 288 ASSERT(is_int32(static_cast<int64_t>(isolate()->heap()->NewSpaceMask())));
289 intptr_t new_space_start = 289 intptr_t new_space_start =
290 reinterpret_cast<intptr_t>(isolate()->heap()->NewSpaceStart()); 290 reinterpret_cast<intptr_t>(isolate()->heap()->NewSpaceStart());
291 Move(kScratchRegister, reinterpret_cast<Address>(-new_space_start), 291 Move(kScratchRegister, reinterpret_cast<Address>(-new_space_start),
292 RelocInfo::NONE64); 292 Assembler::RelocInfoNone());
293 if (scratch.is(object)) { 293 if (scratch.is(object)) {
294 addq(scratch, kScratchRegister); 294 addq(scratch, kScratchRegister);
295 } else { 295 } else {
296 lea(scratch, Operand(object, kScratchRegister, times_1, 0)); 296 lea(scratch, Operand(object, kScratchRegister, times_1, 0));
297 } 297 }
298 and_(scratch, 298 and_(scratch,
299 Immediate(static_cast<int32_t>(isolate()->heap()->NewSpaceMask()))); 299 Immediate(static_cast<int32_t>(isolate()->heap()->NewSpaceMask())));
300 j(cc, branch, distance); 300 j(cc, branch, distance);
301 } 301 }
302 } 302 }
(...skipping 30 matching lines...) Expand all
333 } 333 }
334 334
335 RecordWrite( 335 RecordWrite(
336 object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK); 336 object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK);
337 337
338 bind(&done); 338 bind(&done);
339 339
340 // Clobber clobbered input registers when running with the debug-code flag 340 // Clobber clobbered input registers when running with the debug-code flag
341 // turned on to provoke errors. 341 // turned on to provoke errors.
342 if (emit_debug_code()) { 342 if (emit_debug_code()) {
343 Move(value, kZapValue, RelocInfo::NONE64); 343 Move(value, kZapValue, Assembler::RelocInfoNone());
344 Move(dst, kZapValue, RelocInfo::NONE64); 344 Move(dst, kZapValue, Assembler::RelocInfoNone());
345 } 345 }
346 } 346 }
347 347
348 348
349 void MacroAssembler::RecordWriteArray(Register object, 349 void MacroAssembler::RecordWriteArray(Register object,
350 Register value, 350 Register value,
351 Register index, 351 Register index,
352 SaveFPRegsMode save_fp, 352 SaveFPRegsMode save_fp,
353 RememberedSetAction remembered_set_action, 353 RememberedSetAction remembered_set_action,
354 SmiCheck smi_check) { 354 SmiCheck smi_check) {
(...skipping 12 matching lines...) Expand all
367 FixedArray::kHeaderSize - kHeapObjectTag)); 367 FixedArray::kHeaderSize - kHeapObjectTag));
368 368
369 RecordWrite( 369 RecordWrite(
370 object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK); 370 object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK);
371 371
372 bind(&done); 372 bind(&done);
373 373
374 // Clobber clobbered input registers when running with the debug-code flag 374 // Clobber clobbered input registers when running with the debug-code flag
375 // turned on to provoke errors. 375 // turned on to provoke errors.
376 if (emit_debug_code()) { 376 if (emit_debug_code()) {
377 Move(value, kZapValue, RelocInfo::NONE64); 377 Move(value, kZapValue, Assembler::RelocInfoNone());
378 Move(index, kZapValue, RelocInfo::NONE64); 378 Move(index, kZapValue, Assembler::RelocInfoNone());
379 } 379 }
380 } 380 }
381 381
382 382
383 void MacroAssembler::RecordWrite(Register object, 383 void MacroAssembler::RecordWrite(Register object,
384 Register address, 384 Register address,
385 Register value, 385 Register value,
386 SaveFPRegsMode fp_mode, 386 SaveFPRegsMode fp_mode,
387 RememberedSetAction remembered_set_action, 387 RememberedSetAction remembered_set_action,
388 SmiCheck smi_check) { 388 SmiCheck smi_check) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 Label::kNear); 432 Label::kNear);
433 433
434 RecordWriteStub stub(object, value, address, remembered_set_action, fp_mode); 434 RecordWriteStub stub(object, value, address, remembered_set_action, fp_mode);
435 CallStub(&stub); 435 CallStub(&stub);
436 436
437 bind(&done); 437 bind(&done);
438 438
439 // Clobber clobbered registers when running with the debug-code flag 439 // Clobber clobbered registers when running with the debug-code flag
440 // turned on to provoke errors. 440 // turned on to provoke errors.
441 if (emit_debug_code()) { 441 if (emit_debug_code()) {
442 Move(address, kZapValue, RelocInfo::NONE64); 442 Move(address, kZapValue, Assembler::RelocInfoNone());
443 Move(value, kZapValue, RelocInfo::NONE64); 443 Move(value, kZapValue, Assembler::RelocInfoNone());
444 } 444 }
445 } 445 }
446 446
447 447
448 void MacroAssembler::Assert(Condition cc, BailoutReason reason) { 448 void MacroAssembler::Assert(Condition cc, BailoutReason reason) {
449 if (emit_debug_code()) Check(cc, reason); 449 if (emit_debug_code()) Check(cc, reason);
450 } 450 }
451 451
452 452
453 void MacroAssembler::AssertFastElements(Register elements) { 453 void MacroAssembler::AssertFastElements(Register elements) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 Label ok; 498 Label ok;
499 testl(result, result); 499 testl(result, result);
500 j(not_zero, &ok, Label::kNear); 500 j(not_zero, &ok, Label::kNear);
501 testl(op, op); 501 testl(op, op);
502 j(sign, then_label); 502 j(sign, then_label);
503 bind(&ok); 503 bind(&ok);
504 } 504 }
505 505
506 506
507 void MacroAssembler::Abort(BailoutReason reason) { 507 void MacroAssembler::Abort(BailoutReason reason) {
508 // We want to pass the msg string like a smi to avoid GC 508 #ifdef DEBUG
509 // problems, however msg is not guaranteed to be aligned
510 // properly. Instead, we pass an aligned pointer that is
511 // a proper v8 smi, but also pass the alignment difference
512 // from the real pointer as a smi.
513 const char* msg = GetBailoutReason(reason); 509 const char* msg = GetBailoutReason(reason);
514 intptr_t p1 = reinterpret_cast<intptr_t>(msg);
515 intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag;
516 // Note: p0 might not be a valid Smi _value_, but it has a valid Smi tag.
517 ASSERT(reinterpret_cast<Object*>(p0)->IsSmi());
518 #ifdef DEBUG
519 if (msg != NULL) { 510 if (msg != NULL) {
520 RecordComment("Abort message: "); 511 RecordComment("Abort message: ");
521 RecordComment(msg); 512 RecordComment(msg);
522 } 513 }
523 514
524 if (FLAG_trap_on_abort) { 515 if (FLAG_trap_on_abort) {
525 int3(); 516 int3();
526 return; 517 return;
527 } 518 }
528 #endif 519 #endif
529 520
530 push(rax); 521 push(rax);
531 Move(kScratchRegister, reinterpret_cast<Smi*>(p0), RelocInfo::NONE64); 522 Move(kScratchRegister, Smi::FromInt(static_cast<int>(reason)),
532 push(kScratchRegister); 523 Assembler::RelocInfoNone());
533 Move(kScratchRegister, Smi::FromInt(static_cast<int>(p1 - p0)),
534 RelocInfo::NONE64);
535 push(kScratchRegister); 524 push(kScratchRegister);
536 525
537 if (!has_frame_) { 526 if (!has_frame_) {
538 // We don't actually want to generate a pile of code for this, so just 527 // We don't actually want to generate a pile of code for this, so just
539 // claim there is a stack frame, without generating one. 528 // claim there is a stack frame, without generating one.
540 FrameScope scope(this, StackFrame::NONE); 529 FrameScope scope(this, StackFrame::NONE);
541 CallRuntime(Runtime::kAbort, 2); 530 CallRuntime(Runtime::kAbort, 1);
542 } else { 531 } else {
543 CallRuntime(Runtime::kAbort, 2); 532 CallRuntime(Runtime::kAbort, 1);
544 } 533 }
545 // Control will not return here. 534 // Control will not return here.
546 int3(); 535 int3();
547 } 536 }
548 537
549 538
550 void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) { 539 void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) {
551 ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs 540 ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs
552 Call(stub->GetCode(isolate()), RelocInfo::CODE_TARGET, ast_id); 541 Call(stub->GetCode(isolate()), RelocInfo::CODE_TARGET, ast_id);
553 } 542 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 return static_cast<int>(offset); 652 return static_cast<int>(offset);
664 } 653 }
665 654
666 655
667 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) { 656 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) {
668 EnterApiExitFrame(arg_stack_space); 657 EnterApiExitFrame(arg_stack_space);
669 } 658 }
670 659
671 660
672 void MacroAssembler::CallApiFunctionAndReturn( 661 void MacroAssembler::CallApiFunctionAndReturn(
673 Address function_address, 662 Register function_address,
674 Address thunk_address, 663 Address thunk_address,
675 Register thunk_last_arg, 664 Register thunk_last_arg,
676 int stack_space, 665 int stack_space,
677 Operand return_value_operand, 666 Operand return_value_operand,
678 Operand* context_restore_operand) { 667 Operand* context_restore_operand) {
679 Label prologue; 668 Label prologue;
680 Label promote_scheduled_exception; 669 Label promote_scheduled_exception;
681 Label exception_handled; 670 Label exception_handled;
682 Label delete_allocated_handles; 671 Label delete_allocated_handles;
683 Label leave_exit_frame; 672 Label leave_exit_frame;
684 Label write_back; 673 Label write_back;
685 674
686 Factory* factory = isolate()->factory(); 675 Factory* factory = isolate()->factory();
687 ExternalReference next_address = 676 ExternalReference next_address =
688 ExternalReference::handle_scope_next_address(isolate()); 677 ExternalReference::handle_scope_next_address(isolate());
689 const int kNextOffset = 0; 678 const int kNextOffset = 0;
690 const int kLimitOffset = Offset( 679 const int kLimitOffset = Offset(
691 ExternalReference::handle_scope_limit_address(isolate()), 680 ExternalReference::handle_scope_limit_address(isolate()),
692 next_address); 681 next_address);
693 const int kLevelOffset = Offset( 682 const int kLevelOffset = Offset(
694 ExternalReference::handle_scope_level_address(isolate()), 683 ExternalReference::handle_scope_level_address(isolate()),
695 next_address); 684 next_address);
696 ExternalReference scheduled_exception_address = 685 ExternalReference scheduled_exception_address =
697 ExternalReference::scheduled_exception_address(isolate()); 686 ExternalReference::scheduled_exception_address(isolate());
698 687
688 ASSERT(rdx.is(function_address) || r8.is(function_address));
699 // Allocate HandleScope in callee-save registers. 689 // Allocate HandleScope in callee-save registers.
700 Register prev_next_address_reg = r14; 690 Register prev_next_address_reg = r14;
701 Register prev_limit_reg = rbx; 691 Register prev_limit_reg = rbx;
702 Register base_reg = r15; 692 Register base_reg = r15;
703 Move(base_reg, next_address); 693 Move(base_reg, next_address);
704 movp(prev_next_address_reg, Operand(base_reg, kNextOffset)); 694 movp(prev_next_address_reg, Operand(base_reg, kNextOffset));
705 movp(prev_limit_reg, Operand(base_reg, kLimitOffset)); 695 movp(prev_limit_reg, Operand(base_reg, kLimitOffset));
706 addl(Operand(base_reg, kLevelOffset), Immediate(1)); 696 addl(Operand(base_reg, kLevelOffset), Immediate(1));
707 697
708 if (FLAG_log_timer_events) { 698 if (FLAG_log_timer_events) {
709 FrameScope frame(this, StackFrame::MANUAL); 699 FrameScope frame(this, StackFrame::MANUAL);
710 PushSafepointRegisters(); 700 PushSafepointRegisters();
711 PrepareCallCFunction(1); 701 PrepareCallCFunction(1);
712 LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate())); 702 LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate()));
713 CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1); 703 CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1);
714 PopSafepointRegisters(); 704 PopSafepointRegisters();
715 } 705 }
716 706
717 707
718 Label profiler_disabled; 708 Label profiler_disabled;
719 Label end_profiler_check; 709 Label end_profiler_check;
720 bool* is_profiling_flag = 710 bool* is_profiling_flag =
721 isolate()->cpu_profiler()->is_profiling_address(); 711 isolate()->cpu_profiler()->is_profiling_address();
722 STATIC_ASSERT(sizeof(*is_profiling_flag) == 1); 712 STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
723 Move(rax, is_profiling_flag, RelocInfo::EXTERNAL_REFERENCE); 713 Move(rax, is_profiling_flag, RelocInfo::EXTERNAL_REFERENCE);
724 cmpb(Operand(rax, 0), Immediate(0)); 714 cmpb(Operand(rax, 0), Immediate(0));
725 j(zero, &profiler_disabled); 715 j(zero, &profiler_disabled);
726 716
727 // Third parameter is the address of the actual getter function. 717 // Third parameter is the address of the actual getter function.
728 Move(thunk_last_arg, function_address, RelocInfo::EXTERNAL_REFERENCE); 718 Move(thunk_last_arg, function_address);
729 Move(rax, thunk_address, RelocInfo::EXTERNAL_REFERENCE); 719 Move(rax, thunk_address, RelocInfo::EXTERNAL_REFERENCE);
730 jmp(&end_profiler_check); 720 jmp(&end_profiler_check);
731 721
732 bind(&profiler_disabled); 722 bind(&profiler_disabled);
733 // Call the api function! 723 // Call the api function!
734 Move(rax, reinterpret_cast<Address>(function_address), 724 Move(rax, function_address);
735 RelocInfo::EXTERNAL_REFERENCE);
736 725
737 bind(&end_profiler_check); 726 bind(&end_profiler_check);
738 727
739 // Call the api function! 728 // Call the api function!
740 call(rax); 729 call(rax);
741 730
742 if (FLAG_log_timer_events) { 731 if (FLAG_log_timer_events) {
743 FrameScope frame(this, StackFrame::MANUAL); 732 FrameScope frame(this, StackFrame::MANUAL);
744 PushSafepointRegisters(); 733 PushSafepointRegisters();
745 PrepareCallCFunction(1); 734 PrepareCallCFunction(1);
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 } else if (is_uint32(x)) { 965 } else if (is_uint32(x)) {
977 movl(dst, Immediate(static_cast<uint32_t>(x))); 966 movl(dst, Immediate(static_cast<uint32_t>(x)));
978 } else if (is_int32(x)) { 967 } else if (is_int32(x)) {
979 movq(dst, Immediate(static_cast<int32_t>(x))); 968 movq(dst, Immediate(static_cast<int32_t>(x)));
980 } else { 969 } else {
981 movq(dst, x); 970 movq(dst, x);
982 } 971 }
983 } 972 }
984 973
985 974
986 void MacroAssembler::Set(const Operand& dst, int64_t x) { 975 void MacroAssembler::Set(const Operand& dst, intptr_t x) {
987 if (is_int32(x)) { 976 if (kPointerSize == kInt64Size) {
988 movq(dst, Immediate(static_cast<int32_t>(x))); 977 if (is_int32(x)) {
978 movp(dst, Immediate(static_cast<int32_t>(x)));
979 } else {
980 Set(kScratchRegister, x);
981 movp(dst, kScratchRegister);
982 }
989 } else { 983 } else {
990 Set(kScratchRegister, x); 984 ASSERT(kPointerSize == kInt32Size);
991 movq(dst, kScratchRegister); 985 movp(dst, Immediate(static_cast<int32_t>(x)));
992 } 986 }
993 } 987 }
994 988
995 989
996 // ---------------------------------------------------------------------------- 990 // ----------------------------------------------------------------------------
997 // Smi tagging, untagging and tag detection. 991 // Smi tagging, untagging and tag detection.
998 992
999 bool MacroAssembler::IsUnsafeInt(const int32_t x) { 993 bool MacroAssembler::IsUnsafeInt(const int32_t x) {
1000 static const int kMaxBits = 17; 994 static const int kMaxBits = 17;
1001 return !is_intn(x, kMaxBits); 995 return !is_intn(x, kMaxBits);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 if (value == 1) { 1030 if (value == 1) {
1037 return kSmiConstantRegister; 1031 return kSmiConstantRegister;
1038 } 1032 }
1039 LoadSmiConstant(kScratchRegister, source); 1033 LoadSmiConstant(kScratchRegister, source);
1040 return kScratchRegister; 1034 return kScratchRegister;
1041 } 1035 }
1042 1036
1043 1037
1044 void MacroAssembler::LoadSmiConstant(Register dst, Smi* source) { 1038 void MacroAssembler::LoadSmiConstant(Register dst, Smi* source) {
1045 if (emit_debug_code()) { 1039 if (emit_debug_code()) {
1046 Move(dst, Smi::FromInt(kSmiConstantRegisterValue), RelocInfo::NONE64); 1040 Move(dst, Smi::FromInt(kSmiConstantRegisterValue),
1041 Assembler::RelocInfoNone());
1047 cmpq(dst, kSmiConstantRegister); 1042 cmpq(dst, kSmiConstantRegister);
1048 Assert(equal, kUninitializedKSmiConstantRegister); 1043 Assert(equal, kUninitializedKSmiConstantRegister);
1049 } 1044 }
1050 int value = source->value(); 1045 int value = source->value();
1051 if (value == 0) { 1046 if (value == 0) {
1052 xorl(dst, dst); 1047 xorl(dst, dst);
1053 return; 1048 return;
1054 } 1049 }
1055 bool negative = value < 0; 1050 bool negative = value < 0;
1056 unsigned int uvalue = negative ? -value : value; 1051 unsigned int uvalue = negative ? -value : value;
(...skipping 19 matching lines...) Expand all
1076 case 2: 1071 case 2:
1077 lea(dst, Operand(kSmiConstantRegister, kSmiConstantRegister, times_1, 0)); 1072 lea(dst, Operand(kSmiConstantRegister, kSmiConstantRegister, times_1, 0));
1078 break; 1073 break;
1079 case 1: 1074 case 1:
1080 movp(dst, kSmiConstantRegister); 1075 movp(dst, kSmiConstantRegister);
1081 break; 1076 break;
1082 case 0: 1077 case 0:
1083 UNREACHABLE(); 1078 UNREACHABLE();
1084 return; 1079 return;
1085 default: 1080 default:
1086 Move(dst, source, RelocInfo::NONE64); 1081 Move(dst, source, Assembler::RelocInfoNone());
1087 return; 1082 return;
1088 } 1083 }
1089 if (negative) { 1084 if (negative) {
1090 neg(dst); 1085 neg(dst);
1091 } 1086 }
1092 } 1087 }
1093 1088
1094 1089
1095 void MacroAssembler::Integer32ToSmi(Register dst, Register src) { 1090 void MacroAssembler::Integer32ToSmi(Register dst, Register src) {
1096 STATIC_ASSERT(kSmiTag == 0); 1091 STATIC_ASSERT(kSmiTag == 0);
(...skipping 1486 matching lines...) Expand 10 before | Expand all | Expand 10 after
2583 testb(Operand(src, byte_offset), Immediate(1 << bit_in_byte)); 2578 testb(Operand(src, byte_offset), Immediate(1 << bit_in_byte));
2584 } 2579 }
2585 2580
2586 2581
2587 void MacroAssembler::Jump(ExternalReference ext) { 2582 void MacroAssembler::Jump(ExternalReference ext) {
2588 LoadAddress(kScratchRegister, ext); 2583 LoadAddress(kScratchRegister, ext);
2589 jmp(kScratchRegister); 2584 jmp(kScratchRegister);
2590 } 2585 }
2591 2586
2592 2587
2588 void MacroAssembler::Jump(const Operand& op) {
2589 if (kPointerSize == kInt64Size) {
2590 jmp(op);
2591 } else {
2592 ASSERT(kPointerSize == kInt32Size);
2593 movp(kScratchRegister, op);
2594 jmp(kScratchRegister);
2595 }
2596 }
2597
2598
2593 void MacroAssembler::Jump(Address destination, RelocInfo::Mode rmode) { 2599 void MacroAssembler::Jump(Address destination, RelocInfo::Mode rmode) {
2594 Move(kScratchRegister, destination, rmode); 2600 Move(kScratchRegister, destination, rmode);
2595 jmp(kScratchRegister); 2601 jmp(kScratchRegister);
2596 } 2602 }
2597 2603
2598 2604
2599 void MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) { 2605 void MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) {
2600 // TODO(X64): Inline this 2606 // TODO(X64): Inline this
2601 jmp(code_object, rmode); 2607 jmp(code_object, rmode);
2602 } 2608 }
(...skipping 11 matching lines...) Expand all
2614 int end_position = pc_offset() + CallSize(ext); 2620 int end_position = pc_offset() + CallSize(ext);
2615 #endif 2621 #endif
2616 LoadAddress(kScratchRegister, ext); 2622 LoadAddress(kScratchRegister, ext);
2617 call(kScratchRegister); 2623 call(kScratchRegister);
2618 #ifdef DEBUG 2624 #ifdef DEBUG
2619 CHECK_EQ(end_position, pc_offset()); 2625 CHECK_EQ(end_position, pc_offset());
2620 #endif 2626 #endif
2621 } 2627 }
2622 2628
2623 2629
2630 void MacroAssembler::Call(const Operand& op) {
2631 if (kPointerSize == kInt64Size) {
2632 call(op);
2633 } else {
2634 ASSERT(kPointerSize == kInt32Size);
2635 movp(kScratchRegister, op);
2636 call(kScratchRegister);
2637 }
2638 }
2639
2640
2624 void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { 2641 void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) {
2625 #ifdef DEBUG 2642 #ifdef DEBUG
2626 int end_position = pc_offset() + CallSize(destination, rmode); 2643 int end_position = pc_offset() + CallSize(destination);
2627 #endif 2644 #endif
2628 Move(kScratchRegister, destination, rmode); 2645 Move(kScratchRegister, destination, rmode);
2629 call(kScratchRegister); 2646 call(kScratchRegister);
2630 #ifdef DEBUG 2647 #ifdef DEBUG
2631 CHECK_EQ(pc_offset(), end_position); 2648 CHECK_EQ(pc_offset(), end_position);
2632 #endif 2649 #endif
2633 } 2650 }
2634 2651
2635 2652
2636 void MacroAssembler::Call(Handle<Code> code_object, 2653 void MacroAssembler::Call(Handle<Code> code_object,
(...skipping 1404 matching lines...) Expand 10 before | Expand all | Expand 10 after
4041 } 4058 }
4042 4059
4043 4060
4044 void MacroAssembler::Allocate(int object_size, 4061 void MacroAssembler::Allocate(int object_size,
4045 Register result, 4062 Register result,
4046 Register result_end, 4063 Register result_end,
4047 Register scratch, 4064 Register scratch,
4048 Label* gc_required, 4065 Label* gc_required,
4049 AllocationFlags flags) { 4066 AllocationFlags flags) {
4050 ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 4067 ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0);
4051 ASSERT(object_size <= Page::kMaxNonCodeHeapObjectSize); 4068 ASSERT(object_size <= Page::kMaxRegularHeapObjectSize);
4052 if (!FLAG_inline_new) { 4069 if (!FLAG_inline_new) {
4053 if (emit_debug_code()) { 4070 if (emit_debug_code()) {
4054 // Trash the registers to simulate an allocation failure. 4071 // Trash the registers to simulate an allocation failure.
4055 movl(result, Immediate(0x7091)); 4072 movl(result, Immediate(0x7091));
4056 if (result_end.is_valid()) { 4073 if (result_end.is_valid()) {
4057 movl(result_end, Immediate(0x7191)); 4074 movl(result_end, Immediate(0x7191));
4058 } 4075 }
4059 if (scratch.is_valid()) { 4076 if (scratch.is_valid()) {
4060 movl(scratch, Immediate(0x7291)); 4077 movl(scratch, Immediate(0x7291));
4061 } 4078 }
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
4506 cmpq(map_in_out, FieldOperand(scratch, offset)); 4523 cmpq(map_in_out, FieldOperand(scratch, offset));
4507 j(not_equal, no_map_match); 4524 j(not_equal, no_map_match);
4508 4525
4509 // Use the transitioned cached map. 4526 // Use the transitioned cached map.
4510 offset = transitioned_kind * kPointerSize + 4527 offset = transitioned_kind * kPointerSize +
4511 FixedArrayBase::kHeaderSize; 4528 FixedArrayBase::kHeaderSize;
4512 movp(map_in_out, FieldOperand(scratch, offset)); 4529 movp(map_in_out, FieldOperand(scratch, offset));
4513 } 4530 }
4514 4531
4515 4532
4516 void MacroAssembler::LoadInitialArrayMap(
4517 Register function_in, Register scratch,
4518 Register map_out, bool can_have_holes) {
4519 ASSERT(!function_in.is(map_out));
4520 Label done;
4521 movp(map_out, FieldOperand(function_in,
4522 JSFunction::kPrototypeOrInitialMapOffset));
4523 if (!FLAG_smi_only_arrays) {
4524 ElementsKind kind = can_have_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
4525 LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
4526 kind,
4527 map_out,
4528 scratch,
4529 &done);
4530 } else if (can_have_holes) {
4531 LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
4532 FAST_HOLEY_SMI_ELEMENTS,
4533 map_out,
4534 scratch,
4535 &done);
4536 }
4537 bind(&done);
4538 }
4539
4540 #ifdef _WIN64 4533 #ifdef _WIN64
4541 static const int kRegisterPassedArguments = 4; 4534 static const int kRegisterPassedArguments = 4;
4542 #else 4535 #else
4543 static const int kRegisterPassedArguments = 6; 4536 static const int kRegisterPassedArguments = 6;
4544 #endif 4537 #endif
4545 4538
4546 void MacroAssembler::LoadGlobalFunction(int index, Register function) { 4539 void MacroAssembler::LoadGlobalFunction(int index, Register function) {
4547 // Load the global or builtins object from the current context. 4540 // Load the global or builtins object from the current context.
4548 movp(function, 4541 movp(function,
4549 Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 4542 Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
4550 // Load the native context from the global or builtins object. 4543 // Load the native context from the global or builtins object.
4551 movp(function, FieldOperand(function, GlobalObject::kNativeContextOffset)); 4544 movp(function, FieldOperand(function, GlobalObject::kNativeContextOffset));
4552 // Load the function from the native context. 4545 // Load the function from the native context.
4553 movp(function, Operand(function, Context::SlotOffset(index))); 4546 movp(function, Operand(function, Context::SlotOffset(index)));
4554 } 4547 }
4555 4548
4556 4549
4557 void MacroAssembler::LoadArrayFunction(Register function) {
4558 movp(function,
4559 Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
4560 movp(function, FieldOperand(function, GlobalObject::kGlobalContextOffset));
4561 movp(function,
4562 Operand(function, Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
4563 }
4564
4565
4566 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 4550 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
4567 Register map) { 4551 Register map) {
4568 // Load the initial map. The global functions all have initial maps. 4552 // Load the initial map. The global functions all have initial maps.
4569 movp(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 4553 movp(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
4570 if (emit_debug_code()) { 4554 if (emit_debug_code()) {
4571 Label ok, fail; 4555 Label ok, fail;
4572 CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK); 4556 CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK);
4573 jmp(&ok); 4557 jmp(&ok);
4574 bind(&fail); 4558 bind(&fail);
4575 Abort(kGlobalFunctionsMustHaveInitialMap); 4559 Abort(kGlobalFunctionsMustHaveInitialMap);
(...skipping 20 matching lines...) Expand all
4596 #endif 4580 #endif
4597 } 4581 }
4598 4582
4599 4583
4600 void MacroAssembler::EmitSeqStringSetCharCheck(Register string, 4584 void MacroAssembler::EmitSeqStringSetCharCheck(Register string,
4601 Register index, 4585 Register index,
4602 Register value, 4586 Register value,
4603 uint32_t encoding_mask) { 4587 uint32_t encoding_mask) {
4604 Label is_object; 4588 Label is_object;
4605 JumpIfNotSmi(string, &is_object); 4589 JumpIfNotSmi(string, &is_object);
4606 Throw(kNonObject); 4590 Abort(kNonObject);
4607 bind(&is_object); 4591 bind(&is_object);
4608 4592
4609 push(value); 4593 push(value);
4610 movp(value, FieldOperand(string, HeapObject::kMapOffset)); 4594 movp(value, FieldOperand(string, HeapObject::kMapOffset));
4611 movzxbq(value, FieldOperand(value, Map::kInstanceTypeOffset)); 4595 movzxbq(value, FieldOperand(value, Map::kInstanceTypeOffset));
4612 4596
4613 andb(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); 4597 andb(value, Immediate(kStringRepresentationMask | kStringEncodingMask));
4614 cmpq(value, Immediate(encoding_mask)); 4598 cmpq(value, Immediate(encoding_mask));
4615 pop(value); 4599 pop(value);
4616 ThrowIf(not_equal, kUnexpectedStringType); 4600 Check(equal, kUnexpectedStringType);
4617 4601
4618 // The index is assumed to be untagged coming in, tag it to compare with the 4602 // The index is assumed to be untagged coming in, tag it to compare with the
4619 // string length without using a temp register, it is restored at the end of 4603 // string length without using a temp register, it is restored at the end of
4620 // this function. 4604 // this function.
4621 Integer32ToSmi(index, index); 4605 Integer32ToSmi(index, index);
4622 SmiCompare(index, FieldOperand(string, String::kLengthOffset)); 4606 SmiCompare(index, FieldOperand(string, String::kLengthOffset));
4623 ThrowIf(greater_equal, kIndexIsTooLarge); 4607 Check(less, kIndexIsTooLarge);
4624 4608
4625 SmiCompare(index, Smi::FromInt(0)); 4609 SmiCompare(index, Smi::FromInt(0));
4626 ThrowIf(less, kIndexIsNegative); 4610 Check(greater_equal, kIndexIsNegative);
4627 4611
4628 // Restore the index 4612 // Restore the index
4629 SmiToInteger32(index, index); 4613 SmiToInteger32(index, index);
4630 } 4614 }
4631 4615
4632 4616
4633 void MacroAssembler::PrepareCallCFunction(int num_arguments) { 4617 void MacroAssembler::PrepareCallCFunction(int num_arguments) {
4634 int frame_alignment = OS::ActivationFrameAlignment(); 4618 int frame_alignment = OS::ActivationFrameAlignment();
4635 ASSERT(frame_alignment != 0); 4619 ASSERT(frame_alignment != 0);
4636 ASSERT(num_arguments >= 0); 4620 ASSERT(num_arguments >= 0);
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
4925 4909
4926 // For all objects but the receiver, check that the cache is empty. 4910 // For all objects but the receiver, check that the cache is empty.
4927 EnumLength(rdx, rbx); 4911 EnumLength(rdx, rbx);
4928 Cmp(rdx, Smi::FromInt(0)); 4912 Cmp(rdx, Smi::FromInt(0));
4929 j(not_equal, call_runtime); 4913 j(not_equal, call_runtime);
4930 4914
4931 bind(&start); 4915 bind(&start);
4932 4916
4933 // Check that there are no elements. Register rcx contains the current JS 4917 // Check that there are no elements. Register rcx contains the current JS
4934 // object we've reached through the prototype chain. 4918 // object we've reached through the prototype chain.
4919 Label no_elements;
4935 cmpq(empty_fixed_array_value, 4920 cmpq(empty_fixed_array_value,
4936 FieldOperand(rcx, JSObject::kElementsOffset)); 4921 FieldOperand(rcx, JSObject::kElementsOffset));
4922 j(equal, &no_elements);
4923
4924 // Second chance, the object may be using the empty slow element dictionary.
4925 LoadRoot(kScratchRegister, Heap::kEmptySlowElementDictionaryRootIndex);
4926 cmpq(kScratchRegister, FieldOperand(rcx, JSObject::kElementsOffset));
4937 j(not_equal, call_runtime); 4927 j(not_equal, call_runtime);
4938 4928
4929 bind(&no_elements);
4939 movp(rcx, FieldOperand(rbx, Map::kPrototypeOffset)); 4930 movp(rcx, FieldOperand(rbx, Map::kPrototypeOffset));
4940 cmpq(rcx, null_value); 4931 cmpq(rcx, null_value);
4941 j(not_equal, &next); 4932 j(not_equal, &next);
4942 } 4933 }
4943 4934
4944 void MacroAssembler::TestJSArrayForAllocationMemento( 4935 void MacroAssembler::TestJSArrayForAllocationMemento(
4945 Register receiver_reg, 4936 Register receiver_reg,
4946 Register scratch_reg, 4937 Register scratch_reg,
4947 Label* no_memento_found) { 4938 Label* no_memento_found) {
4948 ExternalReference new_space_start = 4939 ExternalReference new_space_start =
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4984 j(equal, found); 4975 j(equal, found);
4985 movp(current, FieldOperand(current, Map::kPrototypeOffset)); 4976 movp(current, FieldOperand(current, Map::kPrototypeOffset));
4986 CompareRoot(current, Heap::kNullValueRootIndex); 4977 CompareRoot(current, Heap::kNullValueRootIndex);
4987 j(not_equal, &loop_again); 4978 j(not_equal, &loop_again);
4988 } 4979 }
4989 4980
4990 4981
4991 } } // namespace v8::internal 4982 } } // namespace v8::internal
4992 4983
4993 #endif // V8_TARGET_ARCH_X64 4984 #endif // V8_TARGET_ARCH_X64
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