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

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

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 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/ia32/macro-assembler-ia32.h ('k') | src/ia32/simulator-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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 bind(&done); 113 bind(&done);
114 } 114 }
115 } 115 }
116 } 116 }
117 117
118 118
119 void MacroAssembler::RecordWriteHelper(Register object, 119 void MacroAssembler::RecordWriteHelper(Register object,
120 Register addr, 120 Register addr,
121 Register scratch, 121 Register scratch,
122 SaveFPRegsMode save_fp) { 122 SaveFPRegsMode save_fp) {
123 if (FLAG_debug_code) { 123 if (emit_debug_code()) {
124 // Check that the object is not in new space. 124 // Check that the object is not in new space.
125 Label not_in_new_space; 125 Label not_in_new_space;
126 InNewSpace(object, scratch, not_equal, &not_in_new_space); 126 InNewSpace(object, scratch, not_equal, &not_in_new_space);
127 Abort("new-space object passed to RecordWriteHelper"); 127 Abort("new-space object passed to RecordWriteHelper");
128 bind(&not_in_new_space); 128 bind(&not_in_new_space);
129 } 129 }
130 130
131 // Load store buffer top. 131 // Load store buffer top.
132 ExternalReference store_buffer = ExternalReference::store_buffer_top(); 132 ExternalReference store_buffer = ExternalReference::store_buffer_top();
133 mov(scratch, Operand::StaticVariable(store_buffer)); 133 mov(scratch, Operand::StaticVariable(store_buffer));
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 ASSERT_EQ(0, kSmiTag); 191 ASSERT_EQ(0, kSmiTag);
192 lea(dst, Operand(object, dst, times_half_pointer_size, 192 lea(dst, Operand(object, dst, times_half_pointer_size,
193 FixedArray::kHeaderSize - kHeapObjectTag)); 193 FixedArray::kHeaderSize - kHeapObjectTag));
194 } 194 }
195 RecordWriteHelper(object, dst, value, save_fp); 195 RecordWriteHelper(object, dst, value, save_fp);
196 196
197 bind(&done); 197 bind(&done);
198 198
199 // Clobber all input registers when running with the debug-code flag 199 // Clobber all input registers when running with the debug-code flag
200 // turned on to provoke errors. 200 // turned on to provoke errors.
201 if (FLAG_debug_code) { 201 if (emit_debug_code()) {
202 mov(object, Immediate(BitCast<int32_t>(kZapValue))); 202 mov(object, Immediate(BitCast<int32_t>(kZapValue)));
203 mov(value, Immediate(BitCast<int32_t>(kZapValue))); 203 mov(value, Immediate(BitCast<int32_t>(kZapValue)));
204 mov(scratch, Immediate(BitCast<int32_t>(kZapValue))); 204 mov(scratch, Immediate(BitCast<int32_t>(kZapValue)));
205 } 205 }
206 } 206 }
207 207
208 208
209 void MacroAssembler::RecordWrite(Register object, 209 void MacroAssembler::RecordWrite(Register object,
210 Register address, 210 Register address,
211 Register value, 211 Register value,
212 SaveFPRegsMode save_fp) { 212 SaveFPRegsMode save_fp) {
213 // First, check if a write barrier is even needed. The tests below 213 // First, check if a write barrier is even needed. The tests below
214 // catch stores of Smis and stores into young gen. 214 // catch stores of Smis and stores into young gen.
215 Label done; 215 Label done;
216 216
217 // Skip barrier if writing a smi. 217 // Skip barrier if writing a smi.
218 ASSERT_EQ(0, kSmiTag); 218 ASSERT_EQ(0, kSmiTag);
219 test(value, Immediate(kSmiTagMask)); 219 test(value, Immediate(kSmiTagMask));
220 j(zero, &done); 220 j(zero, &done);
221 221
222 InNewSpace(object, value, equal, &done); 222 InNewSpace(object, value, equal, &done);
223 223
224 RecordWriteHelper(object, address, value, save_fp); 224 RecordWriteHelper(object, address, value, save_fp);
225 225
226 bind(&done); 226 bind(&done);
227 227
228 // Clobber all input registers when running with the debug-code flag 228 // Clobber all input registers when running with the debug-code flag
229 // turned on to provoke errors. 229 // turned on to provoke errors.
230 if (FLAG_debug_code) { 230 if (emit_debug_code()) {
231 mov(object, Immediate(BitCast<int32_t>(kZapValue))); 231 mov(object, Immediate(BitCast<int32_t>(kZapValue)));
232 mov(address, Immediate(BitCast<int32_t>(kZapValue))); 232 mov(address, Immediate(BitCast<int32_t>(kZapValue)));
233 mov(value, Immediate(BitCast<int32_t>(kZapValue))); 233 mov(value, Immediate(BitCast<int32_t>(kZapValue)));
234 } 234 }
235 } 235 }
236 236
237 237
238 #ifdef ENABLE_DEBUGGER_SUPPORT 238 #ifdef ENABLE_DEBUGGER_SUPPORT
239 void MacroAssembler::DebugBreak() { 239 void MacroAssembler::DebugBreak() {
240 Set(eax, Immediate(0)); 240 Set(eax, Immediate(0));
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 Assert(not_equal, "Operand is a smi"); 364 Assert(not_equal, "Operand is a smi");
365 } 365 }
366 366
367 367
368 void MacroAssembler::EnterFrame(StackFrame::Type type) { 368 void MacroAssembler::EnterFrame(StackFrame::Type type) {
369 push(ebp); 369 push(ebp);
370 mov(ebp, Operand(esp)); 370 mov(ebp, Operand(esp));
371 push(esi); 371 push(esi);
372 push(Immediate(Smi::FromInt(type))); 372 push(Immediate(Smi::FromInt(type)));
373 push(Immediate(CodeObject())); 373 push(Immediate(CodeObject()));
374 if (FLAG_debug_code) { 374 if (emit_debug_code()) {
375 cmp(Operand(esp, 0), Immediate(Factory::undefined_value())); 375 cmp(Operand(esp, 0), Immediate(Factory::undefined_value()));
376 Check(not_equal, "code object not properly patched"); 376 Check(not_equal, "code object not properly patched");
377 } 377 }
378 } 378 }
379 379
380 380
381 void MacroAssembler::LeaveFrame(StackFrame::Type type) { 381 void MacroAssembler::LeaveFrame(StackFrame::Type type) {
382 if (FLAG_debug_code) { 382 if (emit_debug_code()) {
383 cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), 383 cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset),
384 Immediate(Smi::FromInt(type))); 384 Immediate(Smi::FromInt(type)));
385 Check(equal, "stack frame types must match"); 385 Check(equal, "stack frame types must match");
386 } 386 }
387 leave(); 387 leave();
388 } 388 }
389 389
390 390
391 void MacroAssembler::EnterExitFramePrologue() { 391 void MacroAssembler::EnterExitFramePrologue() {
392 // Setup the frame structure on the stack. 392 // Setup the frame structure on the stack.
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 Register scratch, 629 Register scratch,
630 Label* miss) { 630 Label* miss) {
631 Label same_contexts; 631 Label same_contexts;
632 632
633 ASSERT(!holder_reg.is(scratch)); 633 ASSERT(!holder_reg.is(scratch));
634 634
635 // Load current lexical context from the stack frame. 635 // Load current lexical context from the stack frame.
636 mov(scratch, Operand(ebp, StandardFrameConstants::kContextOffset)); 636 mov(scratch, Operand(ebp, StandardFrameConstants::kContextOffset));
637 637
638 // When generating debug code, make sure the lexical context is set. 638 // When generating debug code, make sure the lexical context is set.
639 if (FLAG_debug_code) { 639 if (emit_debug_code()) {
640 cmp(Operand(scratch), Immediate(0)); 640 cmp(Operand(scratch), Immediate(0));
641 Check(not_equal, "we should not have an empty lexical context"); 641 Check(not_equal, "we should not have an empty lexical context");
642 } 642 }
643 // Load the global context of the current context. 643 // Load the global context of the current context.
644 int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize; 644 int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
645 mov(scratch, FieldOperand(scratch, offset)); 645 mov(scratch, FieldOperand(scratch, offset));
646 mov(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset)); 646 mov(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset));
647 647
648 // Check the context is a global context. 648 // Check the context is a global context.
649 if (FLAG_debug_code) { 649 if (emit_debug_code()) {
650 push(scratch); 650 push(scratch);
651 // Read the first word and compare to global_context_map. 651 // Read the first word and compare to global_context_map.
652 mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); 652 mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
653 cmp(scratch, Factory::global_context_map()); 653 cmp(scratch, Factory::global_context_map());
654 Check(equal, "JSGlobalObject::global_context should be a global context."); 654 Check(equal, "JSGlobalObject::global_context should be a global context.");
655 pop(scratch); 655 pop(scratch);
656 } 656 }
657 657
658 // Check if both contexts are the same. 658 // Check if both contexts are the same.
659 cmp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset)); 659 cmp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
660 j(equal, &same_contexts, taken); 660 j(equal, &same_contexts, taken);
661 661
662 // Compare security tokens, save holder_reg on the stack so we can use it 662 // Compare security tokens, save holder_reg on the stack so we can use it
663 // as a temporary register. 663 // as a temporary register.
664 // 664 //
665 // TODO(119): avoid push(holder_reg)/pop(holder_reg) 665 // TODO(119): avoid push(holder_reg)/pop(holder_reg)
666 push(holder_reg); 666 push(holder_reg);
667 // Check that the security token in the calling global object is 667 // Check that the security token in the calling global object is
668 // compatible with the security token in the receiving global 668 // compatible with the security token in the receiving global
669 // object. 669 // object.
670 mov(holder_reg, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset)); 670 mov(holder_reg, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
671 671
672 // Check the context is a global context. 672 // Check the context is a global context.
673 if (FLAG_debug_code) { 673 if (emit_debug_code()) {
674 cmp(holder_reg, Factory::null_value()); 674 cmp(holder_reg, Factory::null_value());
675 Check(not_equal, "JSGlobalProxy::context() should not be null."); 675 Check(not_equal, "JSGlobalProxy::context() should not be null.");
676 676
677 push(holder_reg); 677 push(holder_reg);
678 // Read the first word and compare to global_context_map(), 678 // Read the first word and compare to global_context_map(),
679 mov(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset)); 679 mov(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset));
680 cmp(holder_reg, Factory::global_context_map()); 680 cmp(holder_reg, Factory::global_context_map());
681 Check(equal, "JSGlobalObject::global_context should be a global context."); 681 Check(equal, "JSGlobalObject::global_context should be a global context.");
682 pop(holder_reg); 682 pop(holder_reg);
683 } 683 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 mov(result, Operand::StaticVariable(new_space_allocation_top)); 716 mov(result, Operand::StaticVariable(new_space_allocation_top));
717 } else { 717 } else {
718 mov(Operand(scratch), Immediate(new_space_allocation_top)); 718 mov(Operand(scratch), Immediate(new_space_allocation_top));
719 mov(result, Operand(scratch, 0)); 719 mov(result, Operand(scratch, 0));
720 } 720 }
721 } 721 }
722 722
723 723
724 void MacroAssembler::UpdateAllocationTopHelper(Register result_end, 724 void MacroAssembler::UpdateAllocationTopHelper(Register result_end,
725 Register scratch) { 725 Register scratch) {
726 if (FLAG_debug_code) { 726 if (emit_debug_code()) {
727 test(result_end, Immediate(kObjectAlignmentMask)); 727 test(result_end, Immediate(kObjectAlignmentMask));
728 Check(zero, "Unaligned allocation in new space"); 728 Check(zero, "Unaligned allocation in new space");
729 } 729 }
730 730
731 ExternalReference new_space_allocation_top = 731 ExternalReference new_space_allocation_top =
732 ExternalReference::new_space_allocation_top_address(); 732 ExternalReference::new_space_allocation_top_address();
733 733
734 // Update new top. Use scratch if available. 734 // Update new top. Use scratch if available.
735 if (scratch.is(no_reg)) { 735 if (scratch.is(no_reg)) {
736 mov(Operand::StaticVariable(new_space_allocation_top), result_end); 736 mov(Operand::StaticVariable(new_space_allocation_top), result_end);
737 } else { 737 } else {
738 mov(Operand(scratch, 0), result_end); 738 mov(Operand(scratch, 0), result_end);
739 } 739 }
740 } 740 }
741 741
742 742
743 void MacroAssembler::AllocateInNewSpace(int object_size, 743 void MacroAssembler::AllocateInNewSpace(int object_size,
744 Register result, 744 Register result,
745 Register result_end, 745 Register result_end,
746 Register scratch, 746 Register scratch,
747 Label* gc_required, 747 Label* gc_required,
748 AllocationFlags flags) { 748 AllocationFlags flags) {
749 if (!FLAG_inline_new) { 749 if (!FLAG_inline_new) {
750 if (FLAG_debug_code) { 750 if (emit_debug_code()) {
751 // Trash the registers to simulate an allocation failure. 751 // Trash the registers to simulate an allocation failure.
752 mov(result, Immediate(0x7091)); 752 mov(result, Immediate(0x7091));
753 if (result_end.is_valid()) { 753 if (result_end.is_valid()) {
754 mov(result_end, Immediate(0x7191)); 754 mov(result_end, Immediate(0x7191));
755 } 755 }
756 if (scratch.is_valid()) { 756 if (scratch.is_valid()) {
757 mov(scratch, Immediate(0x7291)); 757 mov(scratch, Immediate(0x7291));
758 } 758 }
759 } 759 }
760 jmp(gc_required); 760 jmp(gc_required);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 797
798 void MacroAssembler::AllocateInNewSpace(int header_size, 798 void MacroAssembler::AllocateInNewSpace(int header_size,
799 ScaleFactor element_size, 799 ScaleFactor element_size,
800 Register element_count, 800 Register element_count,
801 Register result, 801 Register result,
802 Register result_end, 802 Register result_end,
803 Register scratch, 803 Register scratch,
804 Label* gc_required, 804 Label* gc_required,
805 AllocationFlags flags) { 805 AllocationFlags flags) {
806 if (!FLAG_inline_new) { 806 if (!FLAG_inline_new) {
807 if (FLAG_debug_code) { 807 if (emit_debug_code()) {
808 // Trash the registers to simulate an allocation failure. 808 // Trash the registers to simulate an allocation failure.
809 mov(result, Immediate(0x7091)); 809 mov(result, Immediate(0x7091));
810 mov(result_end, Immediate(0x7191)); 810 mov(result_end, Immediate(0x7191));
811 if (scratch.is_valid()) { 811 if (scratch.is_valid()) {
812 mov(scratch, Immediate(0x7291)); 812 mov(scratch, Immediate(0x7291));
813 } 813 }
814 // Register element_count is not modified by the function. 814 // Register element_count is not modified by the function.
815 } 815 }
816 jmp(gc_required); 816 jmp(gc_required);
817 return; 817 return;
(...skipping 25 matching lines...) Expand all
843 } 843 }
844 844
845 845
846 void MacroAssembler::AllocateInNewSpace(Register object_size, 846 void MacroAssembler::AllocateInNewSpace(Register object_size,
847 Register result, 847 Register result,
848 Register result_end, 848 Register result_end,
849 Register scratch, 849 Register scratch,
850 Label* gc_required, 850 Label* gc_required,
851 AllocationFlags flags) { 851 AllocationFlags flags) {
852 if (!FLAG_inline_new) { 852 if (!FLAG_inline_new) {
853 if (FLAG_debug_code) { 853 if (emit_debug_code()) {
854 // Trash the registers to simulate an allocation failure. 854 // Trash the registers to simulate an allocation failure.
855 mov(result, Immediate(0x7091)); 855 mov(result, Immediate(0x7091));
856 mov(result_end, Immediate(0x7191)); 856 mov(result_end, Immediate(0x7191));
857 if (scratch.is_valid()) { 857 if (scratch.is_valid()) {
858 mov(scratch, Immediate(0x7291)); 858 mov(scratch, Immediate(0x7291));
859 } 859 }
860 // object_size is left unchanged by this function. 860 // object_size is left unchanged by this function.
861 } 861 }
862 jmp(gc_required); 862 jmp(gc_required);
863 return; 863 return;
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
1361 ExternalReference(fid), num_arguments, result_size); 1361 ExternalReference(fid), num_arguments, result_size);
1362 } 1362 }
1363 1363
1364 1364
1365 // If true, a Handle<T> returned by value from a function with cdecl calling 1365 // If true, a Handle<T> returned by value from a function with cdecl calling
1366 // convention will be returned directly as a value of location_ field in a 1366 // convention will be returned directly as a value of location_ field in a
1367 // register eax. 1367 // register eax.
1368 // If false, it is returned as a pointer to a preallocated by caller memory 1368 // If false, it is returned as a pointer to a preallocated by caller memory
1369 // region. Pointer to this region should be passed to a function as an 1369 // region. Pointer to this region should be passed to a function as an
1370 // implicit first argument. 1370 // implicit first argument.
1371 #if defined(USING_BSD_ABI) || defined(__MINGW32__) 1371 #if defined(USING_BSD_ABI) || defined(__MINGW32__) || defined(__CYGWIN__)
1372 static const bool kReturnHandlesDirectly = true; 1372 static const bool kReturnHandlesDirectly = true;
1373 #else 1373 #else
1374 static const bool kReturnHandlesDirectly = false; 1374 static const bool kReturnHandlesDirectly = false;
1375 #endif 1375 #endif
1376 1376
1377 1377
1378 Operand ApiParameterOperand(int index) { 1378 Operand ApiParameterOperand(int index) {
1379 return Operand( 1379 return Operand(
1380 esp, (index + (kReturnHandlesDirectly ? 0 : 1)) * kPointerSize); 1380 esp, (index + (kReturnHandlesDirectly ? 0 : 1)) * kPointerSize);
1381 } 1381 }
(...skipping 16 matching lines...) Expand all
1398 // 1: arg1 1398 // 1: arg1
1399 // 0: pointer to the output cell 1399 // 0: pointer to the output cell
1400 // 1400 //
1401 // Note that this is one more "argument" than the function expects 1401 // Note that this is one more "argument" than the function expects
1402 // so the out cell will have to be popped explicitly after returning 1402 // so the out cell will have to be popped explicitly after returning
1403 // from the function. The out cell contains Handle. 1403 // from the function. The out cell contains Handle.
1404 1404
1405 // pointer to out cell. 1405 // pointer to out cell.
1406 lea(scratch, Operand(esp, (argc + 1) * kPointerSize)); 1406 lea(scratch, Operand(esp, (argc + 1) * kPointerSize));
1407 mov(Operand(esp, 0 * kPointerSize), scratch); // output. 1407 mov(Operand(esp, 0 * kPointerSize), scratch); // output.
1408 if (FLAG_debug_code) { 1408 if (emit_debug_code()) {
1409 mov(Operand(esp, (argc + 1) * kPointerSize), Immediate(0)); // out cell. 1409 mov(Operand(esp, (argc + 1) * kPointerSize), Immediate(0)); // out cell.
1410 } 1410 }
1411 } 1411 }
1412 } 1412 }
1413 1413
1414 1414
1415 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(ApiFunction* function, 1415 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(ApiFunction* function,
1416 int stack_space) { 1416 int stack_space) {
1417 ExternalReference next_address = 1417 ExternalReference next_address =
1418 ExternalReference::handle_scope_next_address(); 1418 ExternalReference::handle_scope_next_address();
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1502 mov(ebx, Immediate(ext)); 1502 mov(ebx, Immediate(ext));
1503 CEntryStub ces(1); 1503 CEntryStub ces(1);
1504 return TryTailCallStub(&ces); 1504 return TryTailCallStub(&ces);
1505 } 1505 }
1506 1506
1507 1507
1508 void MacroAssembler::InvokePrologue(const ParameterCount& expected, 1508 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
1509 const ParameterCount& actual, 1509 const ParameterCount& actual,
1510 Handle<Code> code_constant, 1510 Handle<Code> code_constant,
1511 const Operand& code_operand, 1511 const Operand& code_operand,
1512 Label* done, 1512 NearLabel* done,
1513 InvokeFlag flag, 1513 InvokeFlag flag,
1514 PostCallGenerator* post_call_generator) { 1514 PostCallGenerator* post_call_generator) {
1515 bool definitely_matches = false; 1515 bool definitely_matches = false;
1516 Label invoke; 1516 Label invoke;
1517 if (expected.is_immediate()) { 1517 if (expected.is_immediate()) {
1518 ASSERT(actual.is_immediate()); 1518 ASSERT(actual.is_immediate());
1519 if (expected.immediate() == actual.immediate()) { 1519 if (expected.immediate() == actual.immediate()) {
1520 definitely_matches = true; 1520 definitely_matches = true;
1521 } else { 1521 } else {
1522 mov(eax, actual.immediate()); 1522 mov(eax, actual.immediate());
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1570 bind(&invoke); 1570 bind(&invoke);
1571 } 1571 }
1572 } 1572 }
1573 1573
1574 1574
1575 void MacroAssembler::InvokeCode(const Operand& code, 1575 void MacroAssembler::InvokeCode(const Operand& code,
1576 const ParameterCount& expected, 1576 const ParameterCount& expected,
1577 const ParameterCount& actual, 1577 const ParameterCount& actual,
1578 InvokeFlag flag, 1578 InvokeFlag flag,
1579 PostCallGenerator* post_call_generator) { 1579 PostCallGenerator* post_call_generator) {
1580 Label done; 1580 NearLabel done;
1581 InvokePrologue(expected, actual, Handle<Code>::null(), code, 1581 InvokePrologue(expected, actual, Handle<Code>::null(), code,
1582 &done, flag, post_call_generator); 1582 &done, flag, post_call_generator);
1583 if (flag == CALL_FUNCTION) { 1583 if (flag == CALL_FUNCTION) {
1584 call(code); 1584 call(code);
1585 if (post_call_generator != NULL) post_call_generator->Generate(); 1585 if (post_call_generator != NULL) post_call_generator->Generate();
1586 } else { 1586 } else {
1587 ASSERT(flag == JUMP_FUNCTION); 1587 ASSERT(flag == JUMP_FUNCTION);
1588 jmp(code); 1588 jmp(code);
1589 } 1589 }
1590 bind(&done); 1590 bind(&done);
1591 } 1591 }
1592 1592
1593 1593
1594 void MacroAssembler::InvokeCode(Handle<Code> code, 1594 void MacroAssembler::InvokeCode(Handle<Code> code,
1595 const ParameterCount& expected, 1595 const ParameterCount& expected,
1596 const ParameterCount& actual, 1596 const ParameterCount& actual,
1597 RelocInfo::Mode rmode, 1597 RelocInfo::Mode rmode,
1598 InvokeFlag flag, 1598 InvokeFlag flag,
1599 PostCallGenerator* post_call_generator) { 1599 PostCallGenerator* post_call_generator) {
1600 Label done; 1600 NearLabel done;
1601 Operand dummy(eax); 1601 Operand dummy(eax);
1602 InvokePrologue(expected, actual, code, dummy, &done, 1602 InvokePrologue(expected, actual, code, dummy, &done,
1603 flag, post_call_generator); 1603 flag, post_call_generator);
1604 if (flag == CALL_FUNCTION) { 1604 if (flag == CALL_FUNCTION) {
1605 call(code, rmode); 1605 call(code, rmode);
1606 if (post_call_generator != NULL) post_call_generator->Generate(); 1606 if (post_call_generator != NULL) post_call_generator->Generate();
1607 } else { 1607 } else {
1608 ASSERT(flag == JUMP_FUNCTION); 1608 ASSERT(flag == JUMP_FUNCTION);
1609 jmp(code, rmode); 1609 jmp(code, rmode);
1610 } 1610 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 // Slot is in the current function context. Move it into the 1699 // Slot is in the current function context. Move it into the
1700 // destination register in case we store into it (the write barrier 1700 // destination register in case we store into it (the write barrier
1701 // cannot be allowed to destroy the context in esi). 1701 // cannot be allowed to destroy the context in esi).
1702 mov(dst, esi); 1702 mov(dst, esi);
1703 } 1703 }
1704 1704
1705 // We should not have found a 'with' context by walking the context chain 1705 // We should not have found a 'with' context by walking the context chain
1706 // (i.e., the static scope chain and runtime context chain do not agree). 1706 // (i.e., the static scope chain and runtime context chain do not agree).
1707 // A variable occurring in such a scope should have slot type LOOKUP and 1707 // A variable occurring in such a scope should have slot type LOOKUP and
1708 // not CONTEXT. 1708 // not CONTEXT.
1709 if (FLAG_debug_code) { 1709 if (emit_debug_code()) {
1710 cmp(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX))); 1710 cmp(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
1711 Check(equal, "Yo dawg, I heard you liked function contexts " 1711 Check(equal, "Yo dawg, I heard you liked function contexts "
1712 "so I put function contexts in all your contexts"); 1712 "so I put function contexts in all your contexts");
1713 } 1713 }
1714 } 1714 }
1715 1715
1716 1716
1717 void MacroAssembler::LoadGlobalFunction(int index, Register function) { 1717 void MacroAssembler::LoadGlobalFunction(int index, Register function) {
1718 // Load the global or builtins object from the current context. 1718 // Load the global or builtins object from the current context.
1719 mov(function, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); 1719 mov(function, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
1720 // Load the global context from the global or builtins object. 1720 // Load the global context from the global or builtins object.
1721 mov(function, FieldOperand(function, GlobalObject::kGlobalContextOffset)); 1721 mov(function, FieldOperand(function, GlobalObject::kGlobalContextOffset));
1722 // Load the function from the global context. 1722 // Load the function from the global context.
1723 mov(function, Operand(function, Context::SlotOffset(index))); 1723 mov(function, Operand(function, Context::SlotOffset(index)));
1724 } 1724 }
1725 1725
1726 1726
1727 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 1727 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
1728 Register map) { 1728 Register map) {
1729 // Load the initial map. The global functions all have initial maps. 1729 // Load the initial map. The global functions all have initial maps.
1730 mov(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 1730 mov(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
1731 if (FLAG_debug_code) { 1731 if (emit_debug_code()) {
1732 Label ok, fail; 1732 Label ok, fail;
1733 CheckMap(map, Factory::meta_map(), &fail, false); 1733 CheckMap(map, Factory::meta_map(), &fail, false);
1734 jmp(&ok); 1734 jmp(&ok);
1735 bind(&fail); 1735 bind(&fail);
1736 Abort("Global functions must have initial map"); 1736 Abort("Global functions must have initial map");
1737 bind(&ok); 1737 bind(&ok);
1738 } 1738 }
1739 } 1739 }
1740 1740
1741 1741
1742 // Store the value in register src in the safepoint register stack
1743 // slot for register dst.
1744 void MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) {
1745 mov(SafepointRegisterSlot(dst), src);
1746 }
1747
1748
1749 void MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Immediate src) {
1750 mov(SafepointRegisterSlot(dst), src);
1751 }
1752
1753
1754 void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) {
1755 mov(dst, SafepointRegisterSlot(src));
1756 }
1757
1758
1759 Operand MacroAssembler::SafepointRegisterSlot(Register reg) {
1760 return Operand(esp, SafepointRegisterStackIndex(reg.code()) * kPointerSize);
1761 }
1762
1763
1742 int MacroAssembler::SafepointRegisterStackIndex(int reg_code) { 1764 int MacroAssembler::SafepointRegisterStackIndex(int reg_code) {
1743 // The registers are pushed starting with the lowest encoding, 1765 // The registers are pushed starting with the lowest encoding,
1744 // which means that lowest encodings are furthest away from 1766 // which means that lowest encodings are furthest away from
1745 // the stack pointer. 1767 // the stack pointer.
1746 ASSERT(reg_code >= 0 && reg_code < kNumSafepointRegisters); 1768 ASSERT(reg_code >= 0 && reg_code < kNumSafepointRegisters);
1747 return kNumSafepointRegisters - reg_code - 1; 1769 return kNumSafepointRegisters - reg_code - 1;
1748 } 1770 }
1749 1771
1750 1772
1751 void MacroAssembler::Ret() { 1773 void MacroAssembler::Ret() {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1843 j(NegateCondition(cc), &skip); 1865 j(NegateCondition(cc), &skip);
1844 pushfd(); 1866 pushfd();
1845 DecrementCounter(counter, value); 1867 DecrementCounter(counter, value);
1846 popfd(); 1868 popfd();
1847 bind(&skip); 1869 bind(&skip);
1848 } 1870 }
1849 } 1871 }
1850 1872
1851 1873
1852 void MacroAssembler::Assert(Condition cc, const char* msg) { 1874 void MacroAssembler::Assert(Condition cc, const char* msg) {
1853 if (FLAG_debug_code) Check(cc, msg); 1875 if (emit_debug_code()) Check(cc, msg);
1854 } 1876 }
1855 1877
1856 1878
1857 void MacroAssembler::AssertFastElements(Register elements) { 1879 void MacroAssembler::AssertFastElements(Register elements) {
1858 if (FLAG_debug_code) { 1880 if (emit_debug_code()) {
1859 Label ok; 1881 Label ok;
1860 cmp(FieldOperand(elements, HeapObject::kMapOffset), 1882 cmp(FieldOperand(elements, HeapObject::kMapOffset),
1861 Immediate(Factory::fixed_array_map())); 1883 Immediate(Factory::fixed_array_map()));
1862 j(equal, &ok); 1884 j(equal, &ok);
1863 cmp(FieldOperand(elements, HeapObject::kMapOffset), 1885 cmp(FieldOperand(elements, HeapObject::kMapOffset),
1864 Immediate(Factory::fixed_cow_array_map())); 1886 Immediate(Factory::fixed_cow_array_map()));
1865 j(equal, &ok); 1887 j(equal, &ok);
1866 Abort("JSObject with fast elements map has slow elements"); 1888 Abort("JSObject with fast elements map has slow elements");
1867 bind(&ok); 1889 bind(&ok);
1868 } 1890 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1916 push(Immediate(reinterpret_cast<intptr_t>(Smi::FromInt(p1 - p0)))); 1938 push(Immediate(reinterpret_cast<intptr_t>(Smi::FromInt(p1 - p0))));
1917 CallRuntime(Runtime::kAbort, 2); 1939 CallRuntime(Runtime::kAbort, 2);
1918 // will not return here 1940 // will not return here
1919 int3(); 1941 int3();
1920 } 1942 }
1921 1943
1922 1944
1923 void MacroAssembler::JumpIfNotNumber(Register reg, 1945 void MacroAssembler::JumpIfNotNumber(Register reg,
1924 TypeInfo info, 1946 TypeInfo info,
1925 Label* on_not_number) { 1947 Label* on_not_number) {
1926 if (FLAG_debug_code) AbortIfSmi(reg); 1948 if (emit_debug_code()) AbortIfSmi(reg);
1927 if (!info.IsNumber()) { 1949 if (!info.IsNumber()) {
1928 cmp(FieldOperand(reg, HeapObject::kMapOffset), 1950 cmp(FieldOperand(reg, HeapObject::kMapOffset),
1929 Factory::heap_number_map()); 1951 Factory::heap_number_map());
1930 j(not_equal, on_not_number); 1952 j(not_equal, on_not_number);
1931 } 1953 }
1932 } 1954 }
1933 1955
1934 1956
1935 void MacroAssembler::ConvertToInt32(Register dst, 1957 void MacroAssembler::ConvertToInt32(Register dst,
1936 Register source, 1958 Register source,
1937 Register scratch, 1959 Register scratch,
1938 TypeInfo info, 1960 TypeInfo info,
1939 Label* on_not_int32) { 1961 Label* on_not_int32) {
1940 if (FLAG_debug_code) { 1962 if (emit_debug_code()) {
1941 AbortIfSmi(source); 1963 AbortIfSmi(source);
1942 AbortIfNotNumber(source); 1964 AbortIfNotNumber(source);
1943 } 1965 }
1944 if (info.IsInteger32()) { 1966 if (info.IsInteger32()) {
1945 cvttsd2si(dst, FieldOperand(source, HeapNumber::kValueOffset)); 1967 cvttsd2si(dst, FieldOperand(source, HeapNumber::kValueOffset));
1946 } else { 1968 } else {
1947 Label done; 1969 Label done;
1948 bool push_pop = (scratch.is(no_reg) && dst.is(source)); 1970 bool push_pop = (scratch.is(no_reg) && dst.is(source));
1949 ASSERT(!scratch.is(source)); 1971 ASSERT(!scratch.is(source));
1950 if (push_pop) { 1972 if (push_pop) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2050 int num_arguments) { 2072 int num_arguments) {
2051 // Trashing eax is ok as it will be the return value. 2073 // Trashing eax is ok as it will be the return value.
2052 mov(Operand(eax), Immediate(function)); 2074 mov(Operand(eax), Immediate(function));
2053 CallCFunction(eax, num_arguments); 2075 CallCFunction(eax, num_arguments);
2054 } 2076 }
2055 2077
2056 2078
2057 void MacroAssembler::CallCFunction(Register function, 2079 void MacroAssembler::CallCFunction(Register function,
2058 int num_arguments) { 2080 int num_arguments) {
2059 // Check stack alignment. 2081 // Check stack alignment.
2060 if (FLAG_debug_code) { 2082 if (emit_debug_code()) {
2061 CheckStackAlignment(); 2083 CheckStackAlignment();
2062 } 2084 }
2063 2085
2064 call(Operand(function)); 2086 call(Operand(function));
2065 if (OS::ActivationFrameAlignment() != 0) { 2087 if (OS::ActivationFrameAlignment() != 0) {
2066 mov(esp, Operand(esp, num_arguments * kPointerSize)); 2088 mov(esp, Operand(esp, num_arguments * kPointerSize));
2067 } else { 2089 } else {
2068 add(Operand(esp), Immediate(num_arguments * sizeof(int32_t))); 2090 add(Operand(esp), Immediate(num_arguments * sizeof(int32_t)));
2069 } 2091 }
2070 } 2092 }
(...skipping 14 matching lines...) Expand all
2085 2107
2086 // Check that the code was patched as expected. 2108 // Check that the code was patched as expected.
2087 ASSERT(masm_.pc_ == address_ + size_); 2109 ASSERT(masm_.pc_ == address_ + size_);
2088 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 2110 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
2089 } 2111 }
2090 2112
2091 2113
2092 } } // namespace v8::internal 2114 } } // namespace v8::internal
2093 2115
2094 #endif // V8_TARGET_ARCH_IA32 2116 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/simulator-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698