| OLD | NEW |
| 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 27 matching lines...) Expand all Loading... |
| 38 namespace v8 { | 38 namespace v8 { |
| 39 namespace internal { | 39 namespace internal { |
| 40 | 40 |
| 41 // ------------------------------------------------------------------------- | 41 // ------------------------------------------------------------------------- |
| 42 // MacroAssembler implementation. | 42 // MacroAssembler implementation. |
| 43 | 43 |
| 44 MacroAssembler::MacroAssembler(void* buffer, int size) | 44 MacroAssembler::MacroAssembler(void* buffer, int size) |
| 45 : Assembler(buffer, size), | 45 : Assembler(buffer, size), |
| 46 generating_stub_(false), | 46 generating_stub_(false), |
| 47 allow_stub_calls_(true), | 47 allow_stub_calls_(true), |
| 48 code_object_(HEAP->undefined_value()) { | 48 code_object_(isolate()->heap()->undefined_value()) { |
| 49 } | 49 } |
| 50 | 50 |
| 51 | 51 |
| 52 void MacroAssembler::RecordWriteHelper(Register object, | 52 void MacroAssembler::RecordWriteHelper(Register object, |
| 53 Register addr, | 53 Register addr, |
| 54 Register scratch) { | 54 Register scratch) { |
| 55 if (emit_debug_code()) { | 55 if (emit_debug_code()) { |
| 56 // Check that the object is not in new space. | 56 // Check that the object is not in new space. |
| 57 Label not_in_new_space; | 57 Label not_in_new_space; |
| 58 InNewSpace(object, scratch, not_equal, ¬_in_new_space); | 58 InNewSpace(object, scratch, not_equal, ¬_in_new_space); |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 pop(eax); | 243 pop(eax); |
| 244 } | 244 } |
| 245 } | 245 } |
| 246 | 246 |
| 247 | 247 |
| 248 void MacroAssembler::AbortIfNotNumber(Register object) { | 248 void MacroAssembler::AbortIfNotNumber(Register object) { |
| 249 Label ok; | 249 Label ok; |
| 250 test(object, Immediate(kSmiTagMask)); | 250 test(object, Immediate(kSmiTagMask)); |
| 251 j(zero, &ok); | 251 j(zero, &ok); |
| 252 cmp(FieldOperand(object, HeapObject::kMapOffset), | 252 cmp(FieldOperand(object, HeapObject::kMapOffset), |
| 253 FACTORY->heap_number_map()); | 253 isolate()->factory()->heap_number_map()); |
| 254 Assert(equal, "Operand not a number"); | 254 Assert(equal, "Operand not a number"); |
| 255 bind(&ok); | 255 bind(&ok); |
| 256 } | 256 } |
| 257 | 257 |
| 258 | 258 |
| 259 void MacroAssembler::AbortIfNotSmi(Register object) { | 259 void MacroAssembler::AbortIfNotSmi(Register object) { |
| 260 test(object, Immediate(kSmiTagMask)); | 260 test(object, Immediate(kSmiTagMask)); |
| 261 Assert(equal, "Operand is not a smi"); | 261 Assert(equal, "Operand is not a smi"); |
| 262 } | 262 } |
| 263 | 263 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 279 } | 279 } |
| 280 | 280 |
| 281 | 281 |
| 282 void MacroAssembler::EnterFrame(StackFrame::Type type) { | 282 void MacroAssembler::EnterFrame(StackFrame::Type type) { |
| 283 push(ebp); | 283 push(ebp); |
| 284 mov(ebp, Operand(esp)); | 284 mov(ebp, Operand(esp)); |
| 285 push(esi); | 285 push(esi); |
| 286 push(Immediate(Smi::FromInt(type))); | 286 push(Immediate(Smi::FromInt(type))); |
| 287 push(Immediate(CodeObject())); | 287 push(Immediate(CodeObject())); |
| 288 if (emit_debug_code()) { | 288 if (emit_debug_code()) { |
| 289 cmp(Operand(esp, 0), Immediate(FACTORY->undefined_value())); | 289 cmp(Operand(esp, 0), Immediate(isolate()->factory()->undefined_value())); |
| 290 Check(not_equal, "code object not properly patched"); | 290 Check(not_equal, "code object not properly patched"); |
| 291 } | 291 } |
| 292 } | 292 } |
| 293 | 293 |
| 294 | 294 |
| 295 void MacroAssembler::LeaveFrame(StackFrame::Type type) { | 295 void MacroAssembler::LeaveFrame(StackFrame::Type type) { |
| 296 if (emit_debug_code()) { | 296 if (emit_debug_code()) { |
| 297 cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), | 297 cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), |
| 298 Immediate(Smi::FromInt(type))); | 298 Immediate(Smi::FromInt(type))); |
| 299 Check(equal, "stack frame types must match"); | 299 Check(equal, "stack frame types must match"); |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 // Load the global context of the current context. | 570 // Load the global context of the current context. |
| 571 int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize; | 571 int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize; |
| 572 mov(scratch, FieldOperand(scratch, offset)); | 572 mov(scratch, FieldOperand(scratch, offset)); |
| 573 mov(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset)); | 573 mov(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset)); |
| 574 | 574 |
| 575 // Check the context is a global context. | 575 // Check the context is a global context. |
| 576 if (emit_debug_code()) { | 576 if (emit_debug_code()) { |
| 577 push(scratch); | 577 push(scratch); |
| 578 // Read the first word and compare to global_context_map. | 578 // Read the first word and compare to global_context_map. |
| 579 mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); | 579 mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); |
| 580 cmp(scratch, FACTORY->global_context_map()); | 580 cmp(scratch, isolate()->factory()->global_context_map()); |
| 581 Check(equal, "JSGlobalObject::global_context should be a global context."); | 581 Check(equal, "JSGlobalObject::global_context should be a global context."); |
| 582 pop(scratch); | 582 pop(scratch); |
| 583 } | 583 } |
| 584 | 584 |
| 585 // Check if both contexts are the same. | 585 // Check if both contexts are the same. |
| 586 cmp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset)); | 586 cmp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset)); |
| 587 j(equal, &same_contexts, taken); | 587 j(equal, &same_contexts, taken); |
| 588 | 588 |
| 589 // Compare security tokens, save holder_reg on the stack so we can use it | 589 // Compare security tokens, save holder_reg on the stack so we can use it |
| 590 // as a temporary register. | 590 // as a temporary register. |
| 591 // | 591 // |
| 592 // TODO(119): avoid push(holder_reg)/pop(holder_reg) | 592 // TODO(119): avoid push(holder_reg)/pop(holder_reg) |
| 593 push(holder_reg); | 593 push(holder_reg); |
| 594 // Check that the security token in the calling global object is | 594 // Check that the security token in the calling global object is |
| 595 // compatible with the security token in the receiving global | 595 // compatible with the security token in the receiving global |
| 596 // object. | 596 // object. |
| 597 mov(holder_reg, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset)); | 597 mov(holder_reg, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset)); |
| 598 | 598 |
| 599 // Check the context is a global context. | 599 // Check the context is a global context. |
| 600 if (emit_debug_code()) { | 600 if (emit_debug_code()) { |
| 601 cmp(holder_reg, FACTORY->null_value()); | 601 cmp(holder_reg, isolate()->factory()->null_value()); |
| 602 Check(not_equal, "JSGlobalProxy::context() should not be null."); | 602 Check(not_equal, "JSGlobalProxy::context() should not be null."); |
| 603 | 603 |
| 604 push(holder_reg); | 604 push(holder_reg); |
| 605 // Read the first word and compare to global_context_map(), | 605 // Read the first word and compare to global_context_map(), |
| 606 mov(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset)); | 606 mov(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset)); |
| 607 cmp(holder_reg, FACTORY->global_context_map()); | 607 cmp(holder_reg, isolate()->factory()->global_context_map()); |
| 608 Check(equal, "JSGlobalObject::global_context should be a global context."); | 608 Check(equal, "JSGlobalObject::global_context should be a global context."); |
| 609 pop(holder_reg); | 609 pop(holder_reg); |
| 610 } | 610 } |
| 611 | 611 |
| 612 int token_offset = Context::kHeaderSize + | 612 int token_offset = Context::kHeaderSize + |
| 613 Context::SECURITY_TOKEN_INDEX * kPointerSize; | 613 Context::SECURITY_TOKEN_INDEX * kPointerSize; |
| 614 mov(scratch, FieldOperand(scratch, token_offset)); | 614 mov(scratch, FieldOperand(scratch, token_offset)); |
| 615 cmp(scratch, FieldOperand(holder_reg, token_offset)); | 615 cmp(scratch, FieldOperand(holder_reg, token_offset)); |
| 616 pop(holder_reg); | 616 pop(holder_reg); |
| 617 j(not_equal, miss, not_taken); | 617 j(not_equal, miss, not_taken); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 // Allocate heap number in new space. | 836 // Allocate heap number in new space. |
| 837 AllocateInNewSpace(HeapNumber::kSize, | 837 AllocateInNewSpace(HeapNumber::kSize, |
| 838 result, | 838 result, |
| 839 scratch1, | 839 scratch1, |
| 840 scratch2, | 840 scratch2, |
| 841 gc_required, | 841 gc_required, |
| 842 TAG_OBJECT); | 842 TAG_OBJECT); |
| 843 | 843 |
| 844 // Set the map. | 844 // Set the map. |
| 845 mov(FieldOperand(result, HeapObject::kMapOffset), | 845 mov(FieldOperand(result, HeapObject::kMapOffset), |
| 846 Immediate(FACTORY->heap_number_map())); | 846 Immediate(isolate()->factory()->heap_number_map())); |
| 847 } | 847 } |
| 848 | 848 |
| 849 | 849 |
| 850 void MacroAssembler::AllocateTwoByteString(Register result, | 850 void MacroAssembler::AllocateTwoByteString(Register result, |
| 851 Register length, | 851 Register length, |
| 852 Register scratch1, | 852 Register scratch1, |
| 853 Register scratch2, | 853 Register scratch2, |
| 854 Register scratch3, | 854 Register scratch3, |
| 855 Label* gc_required) { | 855 Label* gc_required) { |
| 856 // Calculate the number of bytes needed for the characters in the string while | 856 // Calculate the number of bytes needed for the characters in the string while |
| 857 // observing object alignment. | 857 // observing object alignment. |
| 858 ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 858 ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
| 859 ASSERT(kShortSize == 2); | 859 ASSERT(kShortSize == 2); |
| 860 // scratch1 = length * 2 + kObjectAlignmentMask. | 860 // scratch1 = length * 2 + kObjectAlignmentMask. |
| 861 lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask)); | 861 lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask)); |
| 862 and_(Operand(scratch1), Immediate(~kObjectAlignmentMask)); | 862 and_(Operand(scratch1), Immediate(~kObjectAlignmentMask)); |
| 863 | 863 |
| 864 // Allocate two byte string in new space. | 864 // Allocate two byte string in new space. |
| 865 AllocateInNewSpace(SeqTwoByteString::kHeaderSize, | 865 AllocateInNewSpace(SeqTwoByteString::kHeaderSize, |
| 866 times_1, | 866 times_1, |
| 867 scratch1, | 867 scratch1, |
| 868 result, | 868 result, |
| 869 scratch2, | 869 scratch2, |
| 870 scratch3, | 870 scratch3, |
| 871 gc_required, | 871 gc_required, |
| 872 TAG_OBJECT); | 872 TAG_OBJECT); |
| 873 | 873 |
| 874 // Set the map, length and hash field. | 874 // Set the map, length and hash field. |
| 875 mov(FieldOperand(result, HeapObject::kMapOffset), | 875 mov(FieldOperand(result, HeapObject::kMapOffset), |
| 876 Immediate(FACTORY->string_map())); | 876 Immediate(isolate()->factory()->string_map())); |
| 877 mov(scratch1, length); | 877 mov(scratch1, length); |
| 878 SmiTag(scratch1); | 878 SmiTag(scratch1); |
| 879 mov(FieldOperand(result, String::kLengthOffset), scratch1); | 879 mov(FieldOperand(result, String::kLengthOffset), scratch1); |
| 880 mov(FieldOperand(result, String::kHashFieldOffset), | 880 mov(FieldOperand(result, String::kHashFieldOffset), |
| 881 Immediate(String::kEmptyHashField)); | 881 Immediate(String::kEmptyHashField)); |
| 882 } | 882 } |
| 883 | 883 |
| 884 | 884 |
| 885 void MacroAssembler::AllocateAsciiString(Register result, | 885 void MacroAssembler::AllocateAsciiString(Register result, |
| 886 Register length, | 886 Register length, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 901 times_1, | 901 times_1, |
| 902 scratch1, | 902 scratch1, |
| 903 result, | 903 result, |
| 904 scratch2, | 904 scratch2, |
| 905 scratch3, | 905 scratch3, |
| 906 gc_required, | 906 gc_required, |
| 907 TAG_OBJECT); | 907 TAG_OBJECT); |
| 908 | 908 |
| 909 // Set the map, length and hash field. | 909 // Set the map, length and hash field. |
| 910 mov(FieldOperand(result, HeapObject::kMapOffset), | 910 mov(FieldOperand(result, HeapObject::kMapOffset), |
| 911 Immediate(FACTORY->ascii_string_map())); | 911 Immediate(isolate()->factory()->ascii_string_map())); |
| 912 mov(scratch1, length); | 912 mov(scratch1, length); |
| 913 SmiTag(scratch1); | 913 SmiTag(scratch1); |
| 914 mov(FieldOperand(result, String::kLengthOffset), scratch1); | 914 mov(FieldOperand(result, String::kLengthOffset), scratch1); |
| 915 mov(FieldOperand(result, String::kHashFieldOffset), | 915 mov(FieldOperand(result, String::kHashFieldOffset), |
| 916 Immediate(String::kEmptyHashField)); | 916 Immediate(String::kEmptyHashField)); |
| 917 } | 917 } |
| 918 | 918 |
| 919 | 919 |
| 920 void MacroAssembler::AllocateAsciiString(Register result, | 920 void MacroAssembler::AllocateAsciiString(Register result, |
| 921 int length, | 921 int length, |
| 922 Register scratch1, | 922 Register scratch1, |
| 923 Register scratch2, | 923 Register scratch2, |
| 924 Label* gc_required) { | 924 Label* gc_required) { |
| 925 ASSERT(length > 0); | 925 ASSERT(length > 0); |
| 926 | 926 |
| 927 // Allocate ascii string in new space. | 927 // Allocate ascii string in new space. |
| 928 AllocateInNewSpace(SeqAsciiString::SizeFor(length), | 928 AllocateInNewSpace(SeqAsciiString::SizeFor(length), |
| 929 result, | 929 result, |
| 930 scratch1, | 930 scratch1, |
| 931 scratch2, | 931 scratch2, |
| 932 gc_required, | 932 gc_required, |
| 933 TAG_OBJECT); | 933 TAG_OBJECT); |
| 934 | 934 |
| 935 // Set the map, length and hash field. | 935 // Set the map, length and hash field. |
| 936 mov(FieldOperand(result, HeapObject::kMapOffset), | 936 mov(FieldOperand(result, HeapObject::kMapOffset), |
| 937 Immediate(FACTORY->ascii_string_map())); | 937 Immediate(isolate()->factory()->ascii_string_map())); |
| 938 mov(FieldOperand(result, String::kLengthOffset), | 938 mov(FieldOperand(result, String::kLengthOffset), |
| 939 Immediate(Smi::FromInt(length))); | 939 Immediate(Smi::FromInt(length))); |
| 940 mov(FieldOperand(result, String::kHashFieldOffset), | 940 mov(FieldOperand(result, String::kHashFieldOffset), |
| 941 Immediate(String::kEmptyHashField)); | 941 Immediate(String::kEmptyHashField)); |
| 942 } | 942 } |
| 943 | 943 |
| 944 | 944 |
| 945 void MacroAssembler::AllocateConsString(Register result, | 945 void MacroAssembler::AllocateConsString(Register result, |
| 946 Register scratch1, | 946 Register scratch1, |
| 947 Register scratch2, | 947 Register scratch2, |
| 948 Label* gc_required) { | 948 Label* gc_required) { |
| 949 // Allocate heap number in new space. | 949 // Allocate heap number in new space. |
| 950 AllocateInNewSpace(ConsString::kSize, | 950 AllocateInNewSpace(ConsString::kSize, |
| 951 result, | 951 result, |
| 952 scratch1, | 952 scratch1, |
| 953 scratch2, | 953 scratch2, |
| 954 gc_required, | 954 gc_required, |
| 955 TAG_OBJECT); | 955 TAG_OBJECT); |
| 956 | 956 |
| 957 // Set the map. The other fields are left uninitialized. | 957 // Set the map. The other fields are left uninitialized. |
| 958 mov(FieldOperand(result, HeapObject::kMapOffset), | 958 mov(FieldOperand(result, HeapObject::kMapOffset), |
| 959 Immediate(FACTORY->cons_string_map())); | 959 Immediate(isolate()->factory()->cons_string_map())); |
| 960 } | 960 } |
| 961 | 961 |
| 962 | 962 |
| 963 void MacroAssembler::AllocateAsciiConsString(Register result, | 963 void MacroAssembler::AllocateAsciiConsString(Register result, |
| 964 Register scratch1, | 964 Register scratch1, |
| 965 Register scratch2, | 965 Register scratch2, |
| 966 Label* gc_required) { | 966 Label* gc_required) { |
| 967 // Allocate heap number in new space. | 967 // Allocate heap number in new space. |
| 968 AllocateInNewSpace(ConsString::kSize, | 968 AllocateInNewSpace(ConsString::kSize, |
| 969 result, | 969 result, |
| 970 scratch1, | 970 scratch1, |
| 971 scratch2, | 971 scratch2, |
| 972 gc_required, | 972 gc_required, |
| 973 TAG_OBJECT); | 973 TAG_OBJECT); |
| 974 | 974 |
| 975 // Set the map. The other fields are left uninitialized. | 975 // Set the map. The other fields are left uninitialized. |
| 976 mov(FieldOperand(result, HeapObject::kMapOffset), | 976 mov(FieldOperand(result, HeapObject::kMapOffset), |
| 977 Immediate(FACTORY->cons_ascii_string_map())); | 977 Immediate(isolate()->factory()->cons_ascii_string_map())); |
| 978 } | 978 } |
| 979 | 979 |
| 980 | 980 |
| 981 // Copy memory, byte-by-byte, from source to destination. Not optimized for | 981 // Copy memory, byte-by-byte, from source to destination. Not optimized for |
| 982 // long or aligned copies. The contents of scratch and length are destroyed. | 982 // long or aligned copies. The contents of scratch and length are destroyed. |
| 983 // Source and destination are incremented by length. | 983 // Source and destination are incremented by length. |
| 984 // Many variants of movsb, loop unrolling, word moves, and indexed operands | 984 // Many variants of movsb, loop unrolling, word moves, and indexed operands |
| 985 // have been tried here already, and this is fastest. | 985 // have been tried here already, and this is fastest. |
| 986 // A simpler loop is faster on small copies, but 30% slower on large ones. | 986 // A simpler loop is faster on small copies, but 30% slower on large ones. |
| 987 // The cld() instruction must have been emitted, to set the direction flag(), | 987 // The cld() instruction must have been emitted, to set the direction flag(), |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1085 test(scratch, Immediate(1 << Map::kHasNonInstancePrototype)); | 1085 test(scratch, Immediate(1 << Map::kHasNonInstancePrototype)); |
| 1086 j(not_zero, &non_instance, not_taken); | 1086 j(not_zero, &non_instance, not_taken); |
| 1087 | 1087 |
| 1088 // Get the prototype or initial map from the function. | 1088 // Get the prototype or initial map from the function. |
| 1089 mov(result, | 1089 mov(result, |
| 1090 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); | 1090 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); |
| 1091 | 1091 |
| 1092 // If the prototype or initial map is the hole, don't return it and | 1092 // If the prototype or initial map is the hole, don't return it and |
| 1093 // simply miss the cache instead. This will allow us to allocate a | 1093 // simply miss the cache instead. This will allow us to allocate a |
| 1094 // prototype object on-demand in the runtime system. | 1094 // prototype object on-demand in the runtime system. |
| 1095 cmp(Operand(result), Immediate(FACTORY->the_hole_value())); | 1095 cmp(Operand(result), Immediate(isolate()->factory()->the_hole_value())); |
| 1096 j(equal, miss, not_taken); | 1096 j(equal, miss, not_taken); |
| 1097 | 1097 |
| 1098 // If the function does not have an initial map, we're done. | 1098 // If the function does not have an initial map, we're done. |
| 1099 Label done; | 1099 Label done; |
| 1100 CmpObjectType(result, MAP_TYPE, scratch); | 1100 CmpObjectType(result, MAP_TYPE, scratch); |
| 1101 j(not_equal, &done); | 1101 j(not_equal, &done); |
| 1102 | 1102 |
| 1103 // Get the prototype from the initial map. | 1103 // Get the prototype from the initial map. |
| 1104 mov(result, FieldOperand(result, Map::kPrototypeOffset)); | 1104 mov(result, FieldOperand(result, Map::kPrototypeOffset)); |
| 1105 jmp(&done); | 1105 jmp(&done); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1151 void MacroAssembler::StubReturn(int argc) { | 1151 void MacroAssembler::StubReturn(int argc) { |
| 1152 ASSERT(argc >= 1 && generating_stub()); | 1152 ASSERT(argc >= 1 && generating_stub()); |
| 1153 ret((argc - 1) * kPointerSize); | 1153 ret((argc - 1) * kPointerSize); |
| 1154 } | 1154 } |
| 1155 | 1155 |
| 1156 | 1156 |
| 1157 void MacroAssembler::IllegalOperation(int num_arguments) { | 1157 void MacroAssembler::IllegalOperation(int num_arguments) { |
| 1158 if (num_arguments > 0) { | 1158 if (num_arguments > 0) { |
| 1159 add(Operand(esp), Immediate(num_arguments * kPointerSize)); | 1159 add(Operand(esp), Immediate(num_arguments * kPointerSize)); |
| 1160 } | 1160 } |
| 1161 mov(eax, Immediate(FACTORY->undefined_value())); | 1161 mov(eax, Immediate(isolate()->factory()->undefined_value())); |
| 1162 } | 1162 } |
| 1163 | 1163 |
| 1164 | 1164 |
| 1165 void MacroAssembler::IndexFromHash(Register hash, Register index) { | 1165 void MacroAssembler::IndexFromHash(Register hash, Register index) { |
| 1166 // The assert checks that the constants for the maximum number of digits | 1166 // The assert checks that the constants for the maximum number of digits |
| 1167 // for an array index cached in the hash field and the number of bits | 1167 // for an array index cached in the hash field and the number of bits |
| 1168 // reserved for it does not conflict. | 1168 // reserved for it does not conflict. |
| 1169 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < | 1169 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < |
| 1170 (1 << String::kArrayIndexValueBits)); | 1170 (1 << String::kArrayIndexValueBits)); |
| 1171 // We want the smi-tagged index in key. kArrayIndexValueMask has zeros in | 1171 // We want the smi-tagged index in key. kArrayIndexValueMask has zeros in |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1222 CallStub(&ces); | 1222 CallStub(&ces); |
| 1223 } | 1223 } |
| 1224 | 1224 |
| 1225 | 1225 |
| 1226 MaybeObject* MacroAssembler::TryCallRuntime(const Runtime::Function* f, | 1226 MaybeObject* MacroAssembler::TryCallRuntime(const Runtime::Function* f, |
| 1227 int num_arguments) { | 1227 int num_arguments) { |
| 1228 if (f->nargs >= 0 && f->nargs != num_arguments) { | 1228 if (f->nargs >= 0 && f->nargs != num_arguments) { |
| 1229 IllegalOperation(num_arguments); | 1229 IllegalOperation(num_arguments); |
| 1230 // Since we did not call the stub, there was no allocation failure. | 1230 // Since we did not call the stub, there was no allocation failure. |
| 1231 // Return some non-failure object. | 1231 // Return some non-failure object. |
| 1232 return HEAP->undefined_value(); | 1232 return isolate()->heap()->undefined_value(); |
| 1233 } | 1233 } |
| 1234 | 1234 |
| 1235 // TODO(1236192): Most runtime routines don't need the number of | 1235 // TODO(1236192): Most runtime routines don't need the number of |
| 1236 // arguments passed in because it is constant. At some point we | 1236 // arguments passed in because it is constant. At some point we |
| 1237 // should remove this need and make the runtime routine entry code | 1237 // should remove this need and make the runtime routine entry code |
| 1238 // smarter. | 1238 // smarter. |
| 1239 Set(eax, Immediate(num_arguments)); | 1239 Set(eax, Immediate(num_arguments)); |
| 1240 mov(ebx, Immediate(ExternalReference(f, isolate()))); | 1240 mov(ebx, Immediate(ExternalReference(f, isolate()))); |
| 1241 CEntryStub ces(1); | 1241 CEntryStub ces(1); |
| 1242 return TryCallStub(&ces); | 1242 return TryCallStub(&ces); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 LeaveApiExitFrame(); | 1396 LeaveApiExitFrame(); |
| 1397 ret(stack_space * kPointerSize); | 1397 ret(stack_space * kPointerSize); |
| 1398 bind(&promote_scheduled_exception); | 1398 bind(&promote_scheduled_exception); |
| 1399 MaybeObject* result = | 1399 MaybeObject* result = |
| 1400 TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); | 1400 TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); |
| 1401 if (result->IsFailure()) { | 1401 if (result->IsFailure()) { |
| 1402 return result; | 1402 return result; |
| 1403 } | 1403 } |
| 1404 bind(&empty_handle); | 1404 bind(&empty_handle); |
| 1405 // It was zero; the result is undefined. | 1405 // It was zero; the result is undefined. |
| 1406 mov(eax, FACTORY->undefined_value()); | 1406 mov(eax, isolate()->factory()->undefined_value()); |
| 1407 jmp(&prologue); | 1407 jmp(&prologue); |
| 1408 | 1408 |
| 1409 // HandleScope limit has changed. Delete allocated extensions. | 1409 // HandleScope limit has changed. Delete allocated extensions. |
| 1410 ExternalReference delete_extensions = | 1410 ExternalReference delete_extensions = |
| 1411 ExternalReference::delete_handle_scope_extensions(isolate()); | 1411 ExternalReference::delete_handle_scope_extensions(isolate()); |
| 1412 bind(&delete_allocated_handles); | 1412 bind(&delete_allocated_handles); |
| 1413 mov(Operand::StaticVariable(limit_address), edi); | 1413 mov(Operand::StaticVariable(limit_address), edi); |
| 1414 mov(edi, eax); | 1414 mov(edi, eax); |
| 1415 mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address())); | 1415 mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address())); |
| 1416 mov(eax, Immediate(delete_extensions)); | 1416 mov(eax, Immediate(delete_extensions)); |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1657 mov(function, Operand(function, Context::SlotOffset(index))); | 1657 mov(function, Operand(function, Context::SlotOffset(index))); |
| 1658 } | 1658 } |
| 1659 | 1659 |
| 1660 | 1660 |
| 1661 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, | 1661 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, |
| 1662 Register map) { | 1662 Register map) { |
| 1663 // Load the initial map. The global functions all have initial maps. | 1663 // Load the initial map. The global functions all have initial maps. |
| 1664 mov(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); | 1664 mov(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); |
| 1665 if (emit_debug_code()) { | 1665 if (emit_debug_code()) { |
| 1666 Label ok, fail; | 1666 Label ok, fail; |
| 1667 CheckMap(map, FACTORY->meta_map(), &fail, false); | 1667 CheckMap(map, isolate()->factory()->meta_map(), &fail, false); |
| 1668 jmp(&ok); | 1668 jmp(&ok); |
| 1669 bind(&fail); | 1669 bind(&fail); |
| 1670 Abort("Global functions must have initial map"); | 1670 Abort("Global functions must have initial map"); |
| 1671 bind(&ok); | 1671 bind(&ok); |
| 1672 } | 1672 } |
| 1673 } | 1673 } |
| 1674 | 1674 |
| 1675 | 1675 |
| 1676 // Store the value in register src in the safepoint register stack | 1676 // Store the value in register src in the safepoint register stack |
| 1677 // slot for register dst. | 1677 // slot for register dst. |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1805 } | 1805 } |
| 1806 | 1806 |
| 1807 | 1807 |
| 1808 void MacroAssembler::Assert(Condition cc, const char* msg) { | 1808 void MacroAssembler::Assert(Condition cc, const char* msg) { |
| 1809 if (emit_debug_code()) Check(cc, msg); | 1809 if (emit_debug_code()) Check(cc, msg); |
| 1810 } | 1810 } |
| 1811 | 1811 |
| 1812 | 1812 |
| 1813 void MacroAssembler::AssertFastElements(Register elements) { | 1813 void MacroAssembler::AssertFastElements(Register elements) { |
| 1814 if (emit_debug_code()) { | 1814 if (emit_debug_code()) { |
| 1815 Factory* factory = isolate()->factory(); |
| 1815 Label ok; | 1816 Label ok; |
| 1816 cmp(FieldOperand(elements, HeapObject::kMapOffset), | 1817 cmp(FieldOperand(elements, HeapObject::kMapOffset), |
| 1817 Immediate(FACTORY->fixed_array_map())); | 1818 Immediate(factory->fixed_array_map())); |
| 1818 j(equal, &ok); | 1819 j(equal, &ok); |
| 1819 cmp(FieldOperand(elements, HeapObject::kMapOffset), | 1820 cmp(FieldOperand(elements, HeapObject::kMapOffset), |
| 1820 Immediate(FACTORY->fixed_cow_array_map())); | 1821 Immediate(factory->fixed_cow_array_map())); |
| 1821 j(equal, &ok); | 1822 j(equal, &ok); |
| 1822 Abort("JSObject with fast elements map has slow elements"); | 1823 Abort("JSObject with fast elements map has slow elements"); |
| 1823 bind(&ok); | 1824 bind(&ok); |
| 1824 } | 1825 } |
| 1825 } | 1826 } |
| 1826 | 1827 |
| 1827 | 1828 |
| 1828 void MacroAssembler::Check(Condition cc, const char* msg) { | 1829 void MacroAssembler::Check(Condition cc, const char* msg) { |
| 1829 Label L; | 1830 Label L; |
| 1830 j(cc, &L, taken); | 1831 j(cc, &L, taken); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1875 int3(); | 1876 int3(); |
| 1876 } | 1877 } |
| 1877 | 1878 |
| 1878 | 1879 |
| 1879 void MacroAssembler::JumpIfNotNumber(Register reg, | 1880 void MacroAssembler::JumpIfNotNumber(Register reg, |
| 1880 TypeInfo info, | 1881 TypeInfo info, |
| 1881 Label* on_not_number) { | 1882 Label* on_not_number) { |
| 1882 if (emit_debug_code()) AbortIfSmi(reg); | 1883 if (emit_debug_code()) AbortIfSmi(reg); |
| 1883 if (!info.IsNumber()) { | 1884 if (!info.IsNumber()) { |
| 1884 cmp(FieldOperand(reg, HeapObject::kMapOffset), | 1885 cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 1885 FACTORY->heap_number_map()); | 1886 isolate()->factory()->heap_number_map()); |
| 1886 j(not_equal, on_not_number); | 1887 j(not_equal, on_not_number); |
| 1887 } | 1888 } |
| 1888 } | 1889 } |
| 1889 | 1890 |
| 1890 | 1891 |
| 1891 void MacroAssembler::ConvertToInt32(Register dst, | 1892 void MacroAssembler::ConvertToInt32(Register dst, |
| 1892 Register source, | 1893 Register source, |
| 1893 Register scratch, | 1894 Register scratch, |
| 1894 TypeInfo info, | 1895 TypeInfo info, |
| 1895 Label* on_not_int32) { | 1896 Label* on_not_int32) { |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2049 | 2050 |
| 2050 // Check that the code was patched as expected. | 2051 // Check that the code was patched as expected. |
| 2051 ASSERT(masm_.pc_ == address_ + size_); | 2052 ASSERT(masm_.pc_ == address_ + size_); |
| 2052 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2053 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
| 2053 } | 2054 } |
| 2054 | 2055 |
| 2055 | 2056 |
| 2056 } } // namespace v8::internal | 2057 } } // namespace v8::internal |
| 2057 | 2058 |
| 2058 #endif // V8_TARGET_ARCH_IA32 | 2059 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |