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

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

Issue 7001025: Remove support for branch hints from the IA32 and X64 assembler. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 7 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/ia32/macro-assembler-ia32.h ('k') | src/ia32/regexp-macro-assembler-ia32.h » ('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 495 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); 506 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize);
507 pop(ebp); 507 pop(ebp);
508 pop(edx); // Remove state. 508 pop(edx); // Remove state.
509 509
510 // Before returning we restore the context from the frame pointer if 510 // Before returning we restore the context from the frame pointer if
511 // not NULL. The frame pointer is NULL in the exception handler of 511 // not NULL. The frame pointer is NULL in the exception handler of
512 // a JS entry frame. 512 // a JS entry frame.
513 Set(esi, Immediate(0)); // Tentatively set context pointer to NULL. 513 Set(esi, Immediate(0)); // Tentatively set context pointer to NULL.
514 Label skip; 514 Label skip;
515 cmp(ebp, 0); 515 cmp(ebp, 0);
516 j(equal, &skip, not_taken, Label::kNear); 516 j(equal, &skip, Label::kNear);
517 mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 517 mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
518 bind(&skip); 518 bind(&skip);
519 519
520 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); 520 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
521 ret(0); 521 ret(0);
522 } 522 }
523 523
524 524
525 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, 525 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
526 Register value) { 526 Register value) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 push(scratch); 607 push(scratch);
608 // Read the first word and compare to global_context_map. 608 // Read the first word and compare to global_context_map.
609 mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); 609 mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
610 cmp(scratch, isolate()->factory()->global_context_map()); 610 cmp(scratch, isolate()->factory()->global_context_map());
611 Check(equal, "JSGlobalObject::global_context should be a global context."); 611 Check(equal, "JSGlobalObject::global_context should be a global context.");
612 pop(scratch); 612 pop(scratch);
613 } 613 }
614 614
615 // Check if both contexts are the same. 615 // Check if both contexts are the same.
616 cmp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset)); 616 cmp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
617 j(equal, &same_contexts, taken); 617 j(equal, &same_contexts);
618 618
619 // Compare security tokens, save holder_reg on the stack so we can use it 619 // Compare security tokens, save holder_reg on the stack so we can use it
620 // as a temporary register. 620 // as a temporary register.
621 // 621 //
622 // TODO(119): avoid push(holder_reg)/pop(holder_reg) 622 // TODO(119): avoid push(holder_reg)/pop(holder_reg)
623 push(holder_reg); 623 push(holder_reg);
624 // Check that the security token in the calling global object is 624 // Check that the security token in the calling global object is
625 // compatible with the security token in the receiving global 625 // compatible with the security token in the receiving global
626 // object. 626 // object.
627 mov(holder_reg, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset)); 627 mov(holder_reg, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
628 628
629 // Check the context is a global context. 629 // Check the context is a global context.
630 if (emit_debug_code()) { 630 if (emit_debug_code()) {
631 cmp(holder_reg, isolate()->factory()->null_value()); 631 cmp(holder_reg, isolate()->factory()->null_value());
632 Check(not_equal, "JSGlobalProxy::context() should not be null."); 632 Check(not_equal, "JSGlobalProxy::context() should not be null.");
633 633
634 push(holder_reg); 634 push(holder_reg);
635 // Read the first word and compare to global_context_map(), 635 // Read the first word and compare to global_context_map(),
636 mov(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset)); 636 mov(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset));
637 cmp(holder_reg, isolate()->factory()->global_context_map()); 637 cmp(holder_reg, isolate()->factory()->global_context_map());
638 Check(equal, "JSGlobalObject::global_context should be a global context."); 638 Check(equal, "JSGlobalObject::global_context should be a global context.");
639 pop(holder_reg); 639 pop(holder_reg);
640 } 640 }
641 641
642 int token_offset = Context::kHeaderSize + 642 int token_offset = Context::kHeaderSize +
643 Context::SECURITY_TOKEN_INDEX * kPointerSize; 643 Context::SECURITY_TOKEN_INDEX * kPointerSize;
644 mov(scratch, FieldOperand(scratch, token_offset)); 644 mov(scratch, FieldOperand(scratch, token_offset));
645 cmp(scratch, FieldOperand(holder_reg, token_offset)); 645 cmp(scratch, FieldOperand(holder_reg, token_offset));
646 pop(holder_reg); 646 pop(holder_reg);
647 j(not_equal, miss, not_taken); 647 j(not_equal, miss);
648 648
649 bind(&same_contexts); 649 bind(&same_contexts);
650 } 650 }
651 651
652 652
653 void MacroAssembler::LoadAllocationTopHelper(Register result, 653 void MacroAssembler::LoadAllocationTopHelper(Register result,
654 Register scratch, 654 Register scratch,
655 AllocationFlags flags) { 655 AllocationFlags flags) {
656 ExternalReference new_space_allocation_top = 656 ExternalReference new_space_allocation_top =
657 ExternalReference::new_space_allocation_top_address(isolate()); 657 ExternalReference::new_space_allocation_top_address(isolate());
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 Register top_reg = result_end.is_valid() ? result_end : result; 725 Register top_reg = result_end.is_valid() ? result_end : result;
726 726
727 // Calculate new top and bail out if new space is exhausted. 727 // Calculate new top and bail out if new space is exhausted.
728 ExternalReference new_space_allocation_limit = 728 ExternalReference new_space_allocation_limit =
729 ExternalReference::new_space_allocation_limit_address(isolate()); 729 ExternalReference::new_space_allocation_limit_address(isolate());
730 730
731 if (!top_reg.is(result)) { 731 if (!top_reg.is(result)) {
732 mov(top_reg, result); 732 mov(top_reg, result);
733 } 733 }
734 add(Operand(top_reg), Immediate(object_size)); 734 add(Operand(top_reg), Immediate(object_size));
735 j(carry, gc_required, not_taken); 735 j(carry, gc_required);
736 cmp(top_reg, Operand::StaticVariable(new_space_allocation_limit)); 736 cmp(top_reg, Operand::StaticVariable(new_space_allocation_limit));
737 j(above, gc_required, not_taken); 737 j(above, gc_required);
738 738
739 // Update allocation top. 739 // Update allocation top.
740 UpdateAllocationTopHelper(top_reg, scratch); 740 UpdateAllocationTopHelper(top_reg, scratch);
741 741
742 // Tag result if requested. 742 // Tag result if requested.
743 if (top_reg.is(result)) { 743 if (top_reg.is(result)) {
744 if ((flags & TAG_OBJECT) != 0) { 744 if ((flags & TAG_OBJECT) != 0) {
745 sub(Operand(result), Immediate(object_size - kHeapObjectTag)); 745 sub(Operand(result), Immediate(object_size - kHeapObjectTag));
746 } else { 746 } else {
747 sub(Operand(result), Immediate(object_size)); 747 sub(Operand(result), Immediate(object_size));
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 // Load address of new object into result. 824 // Load address of new object into result.
825 LoadAllocationTopHelper(result, scratch, flags); 825 LoadAllocationTopHelper(result, scratch, flags);
826 826
827 // Calculate new top and bail out if new space is exhausted. 827 // Calculate new top and bail out if new space is exhausted.
828 ExternalReference new_space_allocation_limit = 828 ExternalReference new_space_allocation_limit =
829 ExternalReference::new_space_allocation_limit_address(isolate()); 829 ExternalReference::new_space_allocation_limit_address(isolate());
830 if (!object_size.is(result_end)) { 830 if (!object_size.is(result_end)) {
831 mov(result_end, object_size); 831 mov(result_end, object_size);
832 } 832 }
833 add(result_end, Operand(result)); 833 add(result_end, Operand(result));
834 j(carry, gc_required, not_taken); 834 j(carry, gc_required);
835 cmp(result_end, Operand::StaticVariable(new_space_allocation_limit)); 835 cmp(result_end, Operand::StaticVariable(new_space_allocation_limit));
836 j(above, gc_required, not_taken); 836 j(above, gc_required);
837 837
838 // Tag result if requested. 838 // Tag result if requested.
839 if ((flags & TAG_OBJECT) != 0) { 839 if ((flags & TAG_OBJECT) != 0) {
840 lea(result, Operand(result, kHeapObjectTag)); 840 lea(result, Operand(result, kHeapObjectTag));
841 } 841 }
842 842
843 // Update allocation top. 843 // Update allocation top.
844 UpdateAllocationTopHelper(result_end, scratch); 844 UpdateAllocationTopHelper(result_end, scratch);
845 } 845 }
846 846
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 1055
1056 bind(&done); 1056 bind(&done);
1057 } 1057 }
1058 1058
1059 1059
1060 void MacroAssembler::NegativeZeroTest(Register result, 1060 void MacroAssembler::NegativeZeroTest(Register result,
1061 Register op, 1061 Register op,
1062 Label* then_label) { 1062 Label* then_label) {
1063 Label ok; 1063 Label ok;
1064 test(result, Operand(result)); 1064 test(result, Operand(result));
1065 j(not_zero, &ok, taken); 1065 j(not_zero, &ok);
1066 test(op, Operand(op)); 1066 test(op, Operand(op));
1067 j(sign, then_label, not_taken); 1067 j(sign, then_label);
1068 bind(&ok); 1068 bind(&ok);
1069 } 1069 }
1070 1070
1071 1071
1072 void MacroAssembler::NegativeZeroTest(Register result, 1072 void MacroAssembler::NegativeZeroTest(Register result,
1073 Register op1, 1073 Register op1,
1074 Register op2, 1074 Register op2,
1075 Register scratch, 1075 Register scratch,
1076 Label* then_label) { 1076 Label* then_label) {
1077 Label ok; 1077 Label ok;
1078 test(result, Operand(result)); 1078 test(result, Operand(result));
1079 j(not_zero, &ok, taken); 1079 j(not_zero, &ok);
1080 mov(scratch, Operand(op1)); 1080 mov(scratch, Operand(op1));
1081 or_(scratch, Operand(op2)); 1081 or_(scratch, Operand(op2));
1082 j(sign, then_label, not_taken); 1082 j(sign, then_label);
1083 bind(&ok); 1083 bind(&ok);
1084 } 1084 }
1085 1085
1086 1086
1087 void MacroAssembler::TryGetFunctionPrototype(Register function, 1087 void MacroAssembler::TryGetFunctionPrototype(Register function,
1088 Register result, 1088 Register result,
1089 Register scratch, 1089 Register scratch,
1090 Label* miss) { 1090 Label* miss) {
1091 // Check that the receiver isn't a smi. 1091 // Check that the receiver isn't a smi.
1092 test(function, Immediate(kSmiTagMask)); 1092 test(function, Immediate(kSmiTagMask));
1093 j(zero, miss, not_taken); 1093 j(zero, miss);
1094 1094
1095 // Check that the function really is a function. 1095 // Check that the function really is a function.
1096 CmpObjectType(function, JS_FUNCTION_TYPE, result); 1096 CmpObjectType(function, JS_FUNCTION_TYPE, result);
1097 j(not_equal, miss, not_taken); 1097 j(not_equal, miss);
1098 1098
1099 // Make sure that the function has an instance prototype. 1099 // Make sure that the function has an instance prototype.
1100 Label non_instance; 1100 Label non_instance;
1101 movzx_b(scratch, FieldOperand(result, Map::kBitFieldOffset)); 1101 movzx_b(scratch, FieldOperand(result, Map::kBitFieldOffset));
1102 test(scratch, Immediate(1 << Map::kHasNonInstancePrototype)); 1102 test(scratch, Immediate(1 << Map::kHasNonInstancePrototype));
1103 j(not_zero, &non_instance, not_taken); 1103 j(not_zero, &non_instance);
1104 1104
1105 // Get the prototype or initial map from the function. 1105 // Get the prototype or initial map from the function.
1106 mov(result, 1106 mov(result,
1107 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 1107 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
1108 1108
1109 // If the prototype or initial map is the hole, don't return it and 1109 // If the prototype or initial map is the hole, don't return it and
1110 // simply miss the cache instead. This will allow us to allocate a 1110 // simply miss the cache instead. This will allow us to allocate a
1111 // prototype object on-demand in the runtime system. 1111 // prototype object on-demand in the runtime system.
1112 cmp(Operand(result), Immediate(isolate()->factory()->the_hole_value())); 1112 cmp(Operand(result), Immediate(isolate()->factory()->the_hole_value()));
1113 j(equal, miss, not_taken); 1113 j(equal, miss);
1114 1114
1115 // If the function does not have an initial map, we're done. 1115 // If the function does not have an initial map, we're done.
1116 Label done; 1116 Label done;
1117 CmpObjectType(result, MAP_TYPE, scratch); 1117 CmpObjectType(result, MAP_TYPE, scratch);
1118 j(not_equal, &done); 1118 j(not_equal, &done);
1119 1119
1120 // Get the prototype from the initial map. 1120 // Get the prototype from the initial map.
1121 mov(result, FieldOperand(result, Map::kPrototypeOffset)); 1121 mov(result, FieldOperand(result, Map::kPrototypeOffset));
1122 jmp(&done); 1122 jmp(&done);
1123 1123
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
1384 } 1384 }
1385 1385
1386 Label empty_handle; 1386 Label empty_handle;
1387 Label prologue; 1387 Label prologue;
1388 Label promote_scheduled_exception; 1388 Label promote_scheduled_exception;
1389 Label delete_allocated_handles; 1389 Label delete_allocated_handles;
1390 Label leave_exit_frame; 1390 Label leave_exit_frame;
1391 1391
1392 // Check if the result handle holds 0. 1392 // Check if the result handle holds 0.
1393 test(eax, Operand(eax)); 1393 test(eax, Operand(eax));
1394 j(zero, &empty_handle, not_taken); 1394 j(zero, &empty_handle);
1395 // It was non-zero. Dereference to get the result value. 1395 // It was non-zero. Dereference to get the result value.
1396 mov(eax, Operand(eax, 0)); 1396 mov(eax, Operand(eax, 0));
1397 bind(&prologue); 1397 bind(&prologue);
1398 // No more valid handles (the result handle was the last one). Restore 1398 // No more valid handles (the result handle was the last one). Restore
1399 // previous handle scope. 1399 // previous handle scope.
1400 mov(Operand::StaticVariable(next_address), ebx); 1400 mov(Operand::StaticVariable(next_address), ebx);
1401 sub(Operand::StaticVariable(level_address), Immediate(1)); 1401 sub(Operand::StaticVariable(level_address), Immediate(1));
1402 Assert(above_equal, "Invalid HandleScope level"); 1402 Assert(above_equal, "Invalid HandleScope level");
1403 cmp(edi, Operand::StaticVariable(limit_address)); 1403 cmp(edi, Operand::StaticVariable(limit_address));
1404 j(not_equal, &delete_allocated_handles, not_taken); 1404 j(not_equal, &delete_allocated_handles);
1405 bind(&leave_exit_frame); 1405 bind(&leave_exit_frame);
1406 1406
1407 // Check if the function scheduled an exception. 1407 // Check if the function scheduled an exception.
1408 ExternalReference scheduled_exception_address = 1408 ExternalReference scheduled_exception_address =
1409 ExternalReference::scheduled_exception_address(isolate()); 1409 ExternalReference::scheduled_exception_address(isolate());
1410 cmp(Operand::StaticVariable(scheduled_exception_address), 1410 cmp(Operand::StaticVariable(scheduled_exception_address),
1411 Immediate(isolate()->factory()->the_hole_value())); 1411 Immediate(isolate()->factory()->the_hole_value()));
1412 j(not_equal, &promote_scheduled_exception, not_taken); 1412 j(not_equal, &promote_scheduled_exception);
1413 LeaveApiExitFrame(); 1413 LeaveApiExitFrame();
1414 ret(stack_space * kPointerSize); 1414 ret(stack_space * kPointerSize);
1415 bind(&promote_scheduled_exception); 1415 bind(&promote_scheduled_exception);
1416 MaybeObject* result = 1416 MaybeObject* result =
1417 TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); 1417 TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
1418 if (result->IsFailure()) { 1418 if (result->IsFailure()) {
1419 return result; 1419 return result;
1420 } 1420 }
1421 bind(&empty_handle); 1421 bind(&empty_handle);
1422 // It was zero; the result is undefined. 1422 // It was zero; the result is undefined.
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
1842 Immediate(factory->fixed_cow_array_map())); 1842 Immediate(factory->fixed_cow_array_map()));
1843 j(equal, &ok); 1843 j(equal, &ok);
1844 Abort("JSObject with fast elements map has slow elements"); 1844 Abort("JSObject with fast elements map has slow elements");
1845 bind(&ok); 1845 bind(&ok);
1846 } 1846 }
1847 } 1847 }
1848 1848
1849 1849
1850 void MacroAssembler::Check(Condition cc, const char* msg) { 1850 void MacroAssembler::Check(Condition cc, const char* msg) {
1851 Label L; 1851 Label L;
1852 j(cc, &L, taken); 1852 j(cc, &L);
1853 Abort(msg); 1853 Abort(msg);
1854 // will not return here 1854 // will not return here
1855 bind(&L); 1855 bind(&L);
1856 } 1856 }
1857 1857
1858 1858
1859 void MacroAssembler::CheckStackAlignment() { 1859 void MacroAssembler::CheckStackAlignment() {
1860 int frame_alignment = OS::ActivationFrameAlignment(); 1860 int frame_alignment = OS::ActivationFrameAlignment();
1861 int frame_alignment_mask = frame_alignment - 1; 1861 int frame_alignment_mask = frame_alignment - 1;
1862 if (frame_alignment > kPointerSize) { 1862 if (frame_alignment > kPointerSize) {
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
2065 2065
2066 // Check that the code was patched as expected. 2066 // Check that the code was patched as expected.
2067 ASSERT(masm_.pc_ == address_ + size_); 2067 ASSERT(masm_.pc_ == address_ + size_);
2068 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 2068 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
2069 } 2069 }
2070 2070
2071 2071
2072 } } // namespace v8::internal 2072 } } // namespace v8::internal
2073 2073
2074 #endif // V8_TARGET_ARCH_IA32 2074 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/regexp-macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698