OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2995 Branch(gc_required, Ugreater, scratch2, Operand(t9)); | 2995 Branch(gc_required, Ugreater, scratch2, Operand(t9)); |
2996 sw(scratch2, MemOperand(topaddr)); | 2996 sw(scratch2, MemOperand(topaddr)); |
2997 | 2997 |
2998 // Tag object if requested. | 2998 // Tag object if requested. |
2999 if ((flags & TAG_OBJECT) != 0) { | 2999 if ((flags & TAG_OBJECT) != 0) { |
3000 Addu(result, result, Operand(kHeapObjectTag)); | 3000 Addu(result, result, Operand(kHeapObjectTag)); |
3001 } | 3001 } |
3002 } | 3002 } |
3003 | 3003 |
3004 | 3004 |
3005 void MacroAssembler::AllocateInNewSpace(Register object_size, | 3005 void MacroAssembler::Allocate(Register object_size, |
3006 Register result, | 3006 Register result, |
3007 Register scratch1, | 3007 Register scratch1, |
3008 Register scratch2, | 3008 Register scratch2, |
3009 Label* gc_required, | 3009 Label* gc_required, |
3010 AllocationFlags flags) { | 3010 AllocationFlags flags) { |
3011 ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); | |
3012 if (!FLAG_inline_new) { | 3011 if (!FLAG_inline_new) { |
3013 if (emit_debug_code()) { | 3012 if (emit_debug_code()) { |
3014 // Trash the registers to simulate an allocation failure. | 3013 // Trash the registers to simulate an allocation failure. |
3015 li(result, 0x7091); | 3014 li(result, 0x7091); |
3016 li(scratch1, 0x7191); | 3015 li(scratch1, 0x7191); |
3017 li(scratch2, 0x7291); | 3016 li(scratch2, 0x7291); |
3018 } | 3017 } |
3019 jmp(gc_required); | 3018 jmp(gc_required); |
3020 return; | 3019 return; |
3021 } | 3020 } |
3022 | 3021 |
3023 ASSERT(!result.is(scratch1)); | 3022 ASSERT(!result.is(scratch1)); |
3024 ASSERT(!result.is(scratch2)); | 3023 ASSERT(!result.is(scratch2)); |
3025 ASSERT(!scratch1.is(scratch2)); | 3024 ASSERT(!scratch1.is(scratch2)); |
3026 ASSERT(!object_size.is(t9)); | 3025 ASSERT(!object_size.is(t9)); |
3027 ASSERT(!scratch1.is(t9) && !scratch2.is(t9) && !result.is(t9)); | 3026 ASSERT(!scratch1.is(t9) && !scratch2.is(t9) && !result.is(t9)); |
3028 | 3027 |
3029 // Check relative positions of allocation top and limit addresses. | 3028 // Check relative positions of allocation top and limit addresses. |
3030 // ARM adds additional checks to make sure the ldm instruction can be | 3029 // ARM adds additional checks to make sure the ldm instruction can be |
3031 // used. On MIPS we don't have ldm so we don't need additional checks either. | 3030 // used. On MIPS we don't have ldm so we don't need additional checks either. |
3032 ExternalReference new_space_allocation_top = | 3031 ExternalReference allocation_top = |
3033 ExternalReference::new_space_allocation_top_address(isolate()); | 3032 AllocationUtils::GetAllocationTopReference(isolate(), flags); |
3034 ExternalReference new_space_allocation_limit = | 3033 ExternalReference allocation_limit = |
3035 ExternalReference::new_space_allocation_limit_address(isolate()); | 3034 AllocationUtils::GetAllocationLimitReference(isolate(), flags); |
3036 intptr_t top = | 3035 intptr_t top = |
3037 reinterpret_cast<intptr_t>(new_space_allocation_top.address()); | 3036 reinterpret_cast<intptr_t>(allocation_top.address()); |
3038 intptr_t limit = | 3037 intptr_t limit = |
3039 reinterpret_cast<intptr_t>(new_space_allocation_limit.address()); | 3038 reinterpret_cast<intptr_t>(allocation_limit.address()); |
3040 ASSERT((limit - top) == kPointerSize); | 3039 ASSERT((limit - top) == kPointerSize); |
3041 | 3040 |
3042 // Set up allocation top address and object size registers. | 3041 // Set up allocation top address and object size registers. |
3043 Register topaddr = scratch1; | 3042 Register topaddr = scratch1; |
3044 li(topaddr, Operand(new_space_allocation_top)); | 3043 li(topaddr, Operand(allocation_top)); |
3045 | 3044 |
3046 // This code stores a temporary value in t9. | 3045 // This code stores a temporary value in t9. |
3047 if ((flags & RESULT_CONTAINS_TOP) == 0) { | 3046 if ((flags & RESULT_CONTAINS_TOP) == 0) { |
3048 // Load allocation top into result and allocation limit into t9. | 3047 // Load allocation top into result and allocation limit into t9. |
3049 lw(result, MemOperand(topaddr)); | 3048 lw(result, MemOperand(topaddr)); |
3050 lw(t9, MemOperand(topaddr, kPointerSize)); | 3049 lw(t9, MemOperand(topaddr, kPointerSize)); |
3051 } else { | 3050 } else { |
3052 if (emit_debug_code()) { | 3051 if (emit_debug_code()) { |
3053 // Assert that result actually contains top on entry. t9 is used | 3052 // Assert that result actually contains top on entry. t9 is used |
3054 // immediately below so this use of t9 does not cause difference with | 3053 // immediately below so this use of t9 does not cause difference with |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3113 Label* gc_required) { | 3112 Label* gc_required) { |
3114 // Calculate the number of bytes needed for the characters in the string while | 3113 // Calculate the number of bytes needed for the characters in the string while |
3115 // observing object alignment. | 3114 // observing object alignment. |
3116 ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 3115 ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
3117 sll(scratch1, length, 1); // Length in bytes, not chars. | 3116 sll(scratch1, length, 1); // Length in bytes, not chars. |
3118 addiu(scratch1, scratch1, | 3117 addiu(scratch1, scratch1, |
3119 kObjectAlignmentMask + SeqTwoByteString::kHeaderSize); | 3118 kObjectAlignmentMask + SeqTwoByteString::kHeaderSize); |
3120 And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); | 3119 And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); |
3121 | 3120 |
3122 // Allocate two-byte string in new space. | 3121 // Allocate two-byte string in new space. |
3123 AllocateInNewSpace(scratch1, | 3122 Allocate(scratch1, |
3124 result, | 3123 result, |
3125 scratch2, | 3124 scratch2, |
3126 scratch3, | 3125 scratch3, |
3127 gc_required, | 3126 gc_required, |
3128 TAG_OBJECT); | 3127 TAG_OBJECT); |
3129 | 3128 |
3130 // Set the map, length and hash field. | 3129 // Set the map, length and hash field. |
3131 InitializeNewString(result, | 3130 InitializeNewString(result, |
3132 length, | 3131 length, |
3133 Heap::kStringMapRootIndex, | 3132 Heap::kStringMapRootIndex, |
3134 scratch1, | 3133 scratch1, |
3135 scratch2); | 3134 scratch2); |
3136 } | 3135 } |
3137 | 3136 |
3138 | 3137 |
3139 void MacroAssembler::AllocateAsciiString(Register result, | 3138 void MacroAssembler::AllocateAsciiString(Register result, |
3140 Register length, | 3139 Register length, |
3141 Register scratch1, | 3140 Register scratch1, |
3142 Register scratch2, | 3141 Register scratch2, |
3143 Register scratch3, | 3142 Register scratch3, |
3144 Label* gc_required) { | 3143 Label* gc_required) { |
3145 // Calculate the number of bytes needed for the characters in the string | 3144 // Calculate the number of bytes needed for the characters in the string |
3146 // while observing object alignment. | 3145 // while observing object alignment. |
3147 ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 3146 ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
3148 ASSERT(kCharSize == 1); | 3147 ASSERT(kCharSize == 1); |
3149 addiu(scratch1, length, kObjectAlignmentMask + SeqOneByteString::kHeaderSize); | 3148 addiu(scratch1, length, kObjectAlignmentMask + SeqOneByteString::kHeaderSize); |
3150 And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); | 3149 And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); |
3151 | 3150 |
3152 // Allocate ASCII string in new space. | 3151 // Allocate ASCII string in new space. |
3153 AllocateInNewSpace(scratch1, | 3152 Allocate(scratch1, |
3154 result, | 3153 result, |
3155 scratch2, | 3154 scratch2, |
3156 scratch3, | 3155 scratch3, |
3157 gc_required, | 3156 gc_required, |
3158 TAG_OBJECT); | 3157 TAG_OBJECT); |
3159 | 3158 |
3160 // Set the map, length and hash field. | 3159 // Set the map, length and hash field. |
3161 InitializeNewString(result, | 3160 InitializeNewString(result, |
3162 length, | 3161 length, |
3163 Heap::kAsciiStringMapRootIndex, | 3162 Heap::kAsciiStringMapRootIndex, |
3164 scratch1, | 3163 scratch1, |
3165 scratch2); | 3164 scratch2); |
3166 } | 3165 } |
3167 | 3166 |
3168 | 3167 |
(...skipping 2394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5563 opcode == BGTZL); | 5562 opcode == BGTZL); |
5564 opcode = (cond == eq) ? BEQ : BNE; | 5563 opcode = (cond == eq) ? BEQ : BNE; |
5565 instr = (instr & ~kOpcodeMask) | opcode; | 5564 instr = (instr & ~kOpcodeMask) | opcode; |
5566 masm_.emit(instr); | 5565 masm_.emit(instr); |
5567 } | 5566 } |
5568 | 5567 |
5569 | 5568 |
5570 } } // namespace v8::internal | 5569 } } // namespace v8::internal |
5571 | 5570 |
5572 #endif // V8_TARGET_ARCH_MIPS | 5571 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |