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 |