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

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

Issue 5512004: Improve code generated for AllocInNewSpace (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 902 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 // Trash the registers to simulate an allocation failure. 913 // Trash the registers to simulate an allocation failure.
914 mov(result, Operand(0x7091)); 914 mov(result, Operand(0x7091));
915 mov(scratch1, Operand(0x7191)); 915 mov(scratch1, Operand(0x7191));
916 mov(scratch2, Operand(0x7291)); 916 mov(scratch2, Operand(0x7291));
917 } 917 }
918 jmp(gc_required); 918 jmp(gc_required);
919 return; 919 return;
920 } 920 }
921 921
922 ASSERT(!result.is(scratch1)); 922 ASSERT(!result.is(scratch1));
923 ASSERT(!result.is(scratch2));
923 ASSERT(!scratch1.is(scratch2)); 924 ASSERT(!scratch1.is(scratch2));
924 925
925 // Make object size into bytes. 926 // Make object size into bytes.
926 if ((flags & SIZE_IN_WORDS) != 0) { 927 if ((flags & SIZE_IN_WORDS) != 0) {
927 object_size *= kPointerSize; 928 object_size *= kPointerSize;
928 } 929 }
929 ASSERT_EQ(0, object_size & kObjectAlignmentMask); 930 ASSERT_EQ(0, object_size & kObjectAlignmentMask);
930 931
931 // Load address of new object into result and allocation top address into 932 // Check relative positions of allocation top and limit addresses.
932 // scratch1. 933 // The values must be adjacent in memory to allow the use of LDM.
934 // Also, assert that the registers are numbered such that the values
935 // are loaded in the correct order.
933 ExternalReference new_space_allocation_top = 936 ExternalReference new_space_allocation_top =
934 ExternalReference::new_space_allocation_top_address(); 937 ExternalReference::new_space_allocation_top_address();
935 mov(scratch1, Operand(new_space_allocation_top)); 938 ExternalReference new_space_allocation_limit =
939 ExternalReference::new_space_allocation_limit_address();
940 uint32_t top =
941 reinterpret_cast<uint32_t>(new_space_allocation_top.address());
942 uint32_t limit =
943 reinterpret_cast<uint32_t>(new_space_allocation_limit.address());
944 ASSERT((limit - top) == 4);
Erik Corry 2010/12/06 09:40:06 Prefer kPointerSize to 4 since it tells the reader
945 ASSERT(result.code() < ip.code());
946
947 // Set up allocation top address and object size registers.
948 Register topaddr = scratch1;
949 Register obj_size_reg = scratch2;
950 mov(topaddr, Operand(new_space_allocation_top));
951 mov(obj_size_reg, Operand(object_size));
952
953 // This code stores a temporary value in ip. This is OK, as the code below
954 // does not need ip for implicit literal generation.
936 if ((flags & RESULT_CONTAINS_TOP) == 0) { 955 if ((flags & RESULT_CONTAINS_TOP) == 0) {
937 ldr(result, MemOperand(scratch1)); 956 // Load allocation top into result and allocation limit into ip.
938 } else if (FLAG_debug_code) { 957 ldm(ia, topaddr, result.bit() | ip.bit());
939 // Assert that result actually contains top on entry. scratch2 is used 958 } else {
940 // immediately below so this use of scratch2 does not cause difference with 959 if (FLAG_debug_code) {
941 // respect to register content between debug and release mode. 960 // Assert that result actually contains top on entry. ip is used
942 ldr(scratch2, MemOperand(scratch1)); 961 // immediately below so this use of ip does not cause difference with
943 cmp(result, scratch2); 962 // respect to register content between debug and release mode.
944 Check(eq, "Unexpected allocation top"); 963 ldr(ip, MemOperand(topaddr));
964 cmp(result, ip);
965 Check(eq, "Unexpected allocation top");
966 }
967 // Load allocation limit into ip. Result already contains allocation top.
968 ldr(ip, MemOperand(topaddr, limit - top));
945 } 969 }
946 970
947 // Calculate new top and bail out if new space is exhausted. Use result 971 // Calculate new top and bail out if new space is exhausted. Use result
948 // to calculate the new top. 972 // to calculate the new top.
949 ExternalReference new_space_allocation_limit = 973 add(scratch2, result, Operand(obj_size_reg));
950 ExternalReference::new_space_allocation_limit_address(); 974 cmp(scratch2, Operand(ip));
951 mov(scratch2, Operand(new_space_allocation_limit));
952 ldr(scratch2, MemOperand(scratch2));
953 add(result, result, Operand(object_size));
954 cmp(result, Operand(scratch2));
955 b(hi, gc_required); 975 b(hi, gc_required);
956 str(result, MemOperand(scratch1)); 976 str(scratch2, MemOperand(topaddr));
957 977
958 // Tag and adjust back to start of new object. 978 // Tag object if requested.
959 if ((flags & TAG_OBJECT) != 0) { 979 if ((flags & TAG_OBJECT) != 0) {
960 sub(result, result, Operand(object_size - kHeapObjectTag)); 980 add(result, result, Operand(kHeapObjectTag));
961 } else {
962 sub(result, result, Operand(object_size));
963 } 981 }
964 } 982 }
965 983
966 984
967 void MacroAssembler::AllocateInNewSpace(Register object_size, 985 void MacroAssembler::AllocateInNewSpace(Register object_size,
968 Register result, 986 Register result,
969 Register scratch1, 987 Register scratch1,
970 Register scratch2, 988 Register scratch2,
971 Label* gc_required, 989 Label* gc_required,
972 AllocationFlags flags) { 990 AllocationFlags flags) {
973 if (!FLAG_inline_new) { 991 if (!FLAG_inline_new) {
974 if (FLAG_debug_code) { 992 if (FLAG_debug_code) {
975 // Trash the registers to simulate an allocation failure. 993 // Trash the registers to simulate an allocation failure.
976 mov(result, Operand(0x7091)); 994 mov(result, Operand(0x7091));
977 mov(scratch1, Operand(0x7191)); 995 mov(scratch1, Operand(0x7191));
978 mov(scratch2, Operand(0x7291)); 996 mov(scratch2, Operand(0x7291));
979 } 997 }
980 jmp(gc_required); 998 jmp(gc_required);
981 return; 999 return;
982 } 1000 }
983 1001
984 ASSERT(!result.is(scratch1)); 1002 ASSERT(!result.is(scratch1));
1003 ASSERT(!result.is(scratch2));
985 ASSERT(!scratch1.is(scratch2)); 1004 ASSERT(!scratch1.is(scratch2));
986 1005
987 // Load address of new object into result and allocation top address into 1006 // Check relative positions of allocation top and limit addresses.
988 // scratch1. 1007 // The values must be adjacent in memory to allow the use of LDM.
1008 // Also, assert that the registers are numbered such that the values
1009 // are loaded in the correct order.
989 ExternalReference new_space_allocation_top = 1010 ExternalReference new_space_allocation_top =
990 ExternalReference::new_space_allocation_top_address(); 1011 ExternalReference::new_space_allocation_top_address();
991 mov(scratch1, Operand(new_space_allocation_top)); 1012 ExternalReference new_space_allocation_limit =
1013 ExternalReference::new_space_allocation_limit_address();
1014 uint32_t top =
1015 reinterpret_cast<uint32_t>(new_space_allocation_top.address());
1016 uint32_t limit =
1017 reinterpret_cast<uint32_t>(new_space_allocation_limit.address());
1018 ASSERT((limit - top) == 4);
1019 ASSERT(result.code() < ip.code());
1020
1021 // Set up allocation top address.
1022 Register topaddr = scratch1;
1023 mov(topaddr, Operand(new_space_allocation_top));
1024
1025 // This code stores a temporary value in ip. This is OK, as the code below
1026 // does not need ip for implicit literal generation.
992 if ((flags & RESULT_CONTAINS_TOP) == 0) { 1027 if ((flags & RESULT_CONTAINS_TOP) == 0) {
993 ldr(result, MemOperand(scratch1)); 1028 // Load allocation top into result and allocation limit into ip.
994 } else if (FLAG_debug_code) { 1029 ldm(ia, topaddr, result.bit() | ip.bit());
995 // Assert that result actually contains top on entry. scratch2 is used 1030 } else {
996 // immediately below so this use of scratch2 does not cause difference with 1031 if (FLAG_debug_code) {
997 // respect to register content between debug and release mode. 1032 // Assert that result actually contains top on entry. ip is used
998 ldr(scratch2, MemOperand(scratch1)); 1033 // immediately below so this use of ip does not cause difference with
999 cmp(result, scratch2); 1034 // respect to register content between debug and release mode.
1000 Check(eq, "Unexpected allocation top"); 1035 ldr(ip, MemOperand(topaddr));
1036 cmp(result, ip);
1037 Check(eq, "Unexpected allocation top");
1038 }
1039 // Load allocation limit into ip. Result already contains allocation top.
1040 ldr(ip, MemOperand(topaddr, limit - top));
1001 } 1041 }
1002 1042
1003 // Calculate new top and bail out if new space is exhausted. Use result 1043 // Calculate new top and bail out if new space is exhausted. Use result
1004 // to calculate the new top. Object size is in words so a shift is required to 1044 // to calculate the new top. Object size may be in words so a shift is
1005 // get the number of bytes 1045 // required to get the number of bytes.
1006 ExternalReference new_space_allocation_limit =
1007 ExternalReference::new_space_allocation_limit_address();
1008 mov(scratch2, Operand(new_space_allocation_limit));
1009 ldr(scratch2, MemOperand(scratch2));
1010 if ((flags & SIZE_IN_WORDS) != 0) { 1046 if ((flags & SIZE_IN_WORDS) != 0) {
1011 add(result, result, Operand(object_size, LSL, kPointerSizeLog2)); 1047 add(scratch2, result, Operand(object_size, LSL, kPointerSizeLog2));
1012 } else { 1048 } else {
1013 add(result, result, Operand(object_size)); 1049 add(scratch2, result, Operand(object_size));
1014 } 1050 }
1015 cmp(result, Operand(scratch2)); 1051 cmp(scratch2, Operand(ip));
1016 b(hi, gc_required); 1052 b(hi, gc_required);
1017 1053
1018 // Update allocation top. result temporarily holds the new top. 1054 // Update allocation top. result temporarily holds the new top.
1019 if (FLAG_debug_code) { 1055 if (FLAG_debug_code) {
1020 tst(result, Operand(kObjectAlignmentMask)); 1056 tst(scratch2, Operand(kObjectAlignmentMask));
1021 Check(eq, "Unaligned allocation in new space"); 1057 Check(eq, "Unaligned allocation in new space");
1022 } 1058 }
1023 str(result, MemOperand(scratch1)); 1059 str(scratch2, MemOperand(topaddr));
1024
1025 // Adjust back to start of new object.
1026 if ((flags & SIZE_IN_WORDS) != 0) {
1027 sub(result, result, Operand(object_size, LSL, kPointerSizeLog2));
1028 } else {
1029 sub(result, result, Operand(object_size));
1030 }
1031 1060
1032 // Tag object if requested. 1061 // Tag object if requested.
1033 if ((flags & TAG_OBJECT) != 0) { 1062 if ((flags & TAG_OBJECT) != 0) {
1034 add(result, result, Operand(kHeapObjectTag)); 1063 add(result, result, Operand(kHeapObjectTag));
1035 } 1064 }
1036 } 1065 }
1037 1066
1038 1067
1039 void MacroAssembler::UndoAllocationInNewSpace(Register object, 1068 void MacroAssembler::UndoAllocationInNewSpace(Register object,
1040 Register scratch) { 1069 Register scratch) {
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after
2002 2031
2003 void CodePatcher::Emit(Address addr) { 2032 void CodePatcher::Emit(Address addr) {
2004 masm()->emit(reinterpret_cast<Instr>(addr)); 2033 masm()->emit(reinterpret_cast<Instr>(addr));
2005 } 2034 }
2006 #endif // ENABLE_DEBUGGER_SUPPORT 2035 #endif // ENABLE_DEBUGGER_SUPPORT
2007 2036
2008 2037
2009 } } // namespace v8::internal 2038 } } // namespace v8::internal
2010 2039
2011 #endif // V8_TARGET_ARCH_ARM 2040 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698