| 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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 | 200 |
| 201 if (info()->saves_caller_doubles()) { | 201 if (info()->saves_caller_doubles()) { |
| 202 SaveCallerDoubles(); | 202 SaveCallerDoubles(); |
| 203 } | 203 } |
| 204 | 204 |
| 205 // Possibly allocate a local context. | 205 // Possibly allocate a local context. |
| 206 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 206 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 207 if (heap_slots > 0) { | 207 if (heap_slots > 0) { |
| 208 Comment(";;; Allocate local context"); | 208 Comment(";;; Allocate local context"); |
| 209 // Argument to NewContext is the function, which is in r1. | 209 // Argument to NewContext is the function, which is in r1. |
| 210 __ push(r1); | |
| 211 if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 210 if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
| 212 FastNewContextStub stub(heap_slots); | 211 FastNewContextStub stub(heap_slots); |
| 213 __ CallStub(&stub); | 212 __ CallStub(&stub); |
| 214 } else { | 213 } else { |
| 214 __ push(r1); |
| 215 __ CallRuntime(Runtime::kNewFunctionContext, 1); | 215 __ CallRuntime(Runtime::kNewFunctionContext, 1); |
| 216 } | 216 } |
| 217 RecordSafepoint(Safepoint::kNoLazyDeopt); | 217 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 218 // Context is returned in both r0 and cp. It replaces the context | 218 // Context is returned in both r0 and cp. It replaces the context |
| 219 // passed to us. It's saved in the stack and kept live in cp. | 219 // passed to us. It's saved in the stack and kept live in cp. |
| 220 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 220 __ mov(cp, r0); |
| 221 __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 221 // Copy any necessary parameters into the context. | 222 // Copy any necessary parameters into the context. |
| 222 int num_parameters = scope()->num_parameters(); | 223 int num_parameters = scope()->num_parameters(); |
| 223 for (int i = 0; i < num_parameters; i++) { | 224 for (int i = 0; i < num_parameters; i++) { |
| 224 Variable* var = scope()->parameter(i); | 225 Variable* var = scope()->parameter(i); |
| 225 if (var->IsContextSlot()) { | 226 if (var->IsContextSlot()) { |
| 226 int parameter_offset = StandardFrameConstants::kCallerSPOffset + | 227 int parameter_offset = StandardFrameConstants::kCallerSPOffset + |
| 227 (num_parameters - 1 - i) * kPointerSize; | 228 (num_parameters - 1 - i) * kPointerSize; |
| 228 // Load parameter from stack. | 229 // Load parameter from stack. |
| 229 __ ldr(r0, MemOperand(fp, parameter_offset)); | 230 __ ldr(r0, MemOperand(fp, parameter_offset)); |
| 230 // Store it in the context. | 231 // Store it in the context. |
| (...skipping 2763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2994 __ CompareRoot(payload, Heap::kTheHoleValueRootIndex); | 2995 __ CompareRoot(payload, Heap::kTheHoleValueRootIndex); |
| 2995 DeoptimizeIf(eq, instr->environment()); | 2996 DeoptimizeIf(eq, instr->environment()); |
| 2996 } | 2997 } |
| 2997 | 2998 |
| 2998 // Store the value. | 2999 // Store the value. |
| 2999 __ str(value, FieldMemOperand(cell, Cell::kValueOffset)); | 3000 __ str(value, FieldMemOperand(cell, Cell::kValueOffset)); |
| 3000 // Cells are always rescanned, so no write barrier here. | 3001 // Cells are always rescanned, so no write barrier here. |
| 3001 } | 3002 } |
| 3002 | 3003 |
| 3003 | 3004 |
| 3004 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { | |
| 3005 ASSERT(ToRegister(instr->context()).is(cp)); | |
| 3006 ASSERT(ToRegister(instr->global_object()).is(r1)); | |
| 3007 ASSERT(ToRegister(instr->value()).is(r0)); | |
| 3008 | |
| 3009 __ mov(r2, Operand(instr->name())); | |
| 3010 Handle<Code> ic = StoreIC::initialize_stub(isolate(), | |
| 3011 instr->strict_mode_flag(), | |
| 3012 CONTEXTUAL); | |
| 3013 CallCode(ic, RelocInfo::CODE_TARGET, instr); | |
| 3014 } | |
| 3015 | |
| 3016 | |
| 3017 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 3005 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
| 3018 Register context = ToRegister(instr->context()); | 3006 Register context = ToRegister(instr->context()); |
| 3019 Register result = ToRegister(instr->result()); | 3007 Register result = ToRegister(instr->result()); |
| 3020 __ ldr(result, ContextOperand(context, instr->slot_index())); | 3008 __ ldr(result, ContextOperand(context, instr->slot_index())); |
| 3021 if (instr->hydrogen()->RequiresHoleCheck()) { | 3009 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3022 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 3010 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 3023 __ cmp(result, ip); | 3011 __ cmp(result, ip); |
| 3024 if (instr->hydrogen()->DeoptimizesOnHole()) { | 3012 if (instr->hydrogen()->DeoptimizesOnHole()) { |
| 3025 DeoptimizeIf(eq, instr->environment()); | 3013 DeoptimizeIf(eq, instr->environment()); |
| 3026 } else { | 3014 } else { |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3213 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3201 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 3214 if (constant_key & 0xF0000000) { | 3202 if (constant_key & 0xF0000000) { |
| 3215 Abort(kArrayIndexConstantValueTooBig); | 3203 Abort(kArrayIndexConstantValueTooBig); |
| 3216 } | 3204 } |
| 3217 } else { | 3205 } else { |
| 3218 key = ToRegister(instr->key()); | 3206 key = ToRegister(instr->key()); |
| 3219 } | 3207 } |
| 3220 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3208 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 3221 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 3209 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 3222 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 3210 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 3223 int additional_offset = instr->additional_index() << element_size_shift; | 3211 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) |
| 3212 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag |
| 3213 : 0; |
| 3214 |
| 3224 | 3215 |
| 3225 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 3216 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 3226 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3217 elements_kind == FLOAT32_ELEMENTS || |
| 3218 elements_kind == EXTERNAL_DOUBLE_ELEMENTS || |
| 3219 elements_kind == FLOAT64_ELEMENTS) { |
| 3220 int base_offset = |
| 3221 (instr->additional_index() << element_size_shift) + additional_offset; |
| 3227 DwVfpRegister result = ToDoubleRegister(instr->result()); | 3222 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 3228 Operand operand = key_is_constant | 3223 Operand operand = key_is_constant |
| 3229 ? Operand(constant_key << element_size_shift) | 3224 ? Operand(constant_key << element_size_shift) |
| 3230 : Operand(key, LSL, shift_size); | 3225 : Operand(key, LSL, shift_size); |
| 3231 __ add(scratch0(), external_pointer, operand); | 3226 __ add(scratch0(), external_pointer, operand); |
| 3232 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3227 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 3233 __ vldr(double_scratch0().low(), scratch0(), additional_offset); | 3228 elements_kind == FLOAT32_ELEMENTS) { |
| 3229 __ vldr(double_scratch0().low(), scratch0(), base_offset); |
| 3234 __ vcvt_f64_f32(result, double_scratch0().low()); | 3230 __ vcvt_f64_f32(result, double_scratch0().low()); |
| 3235 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 3231 } else { // loading doubles, not floats. |
| 3236 __ vldr(result, scratch0(), additional_offset); | 3232 __ vldr(result, scratch0(), base_offset); |
| 3237 } | 3233 } |
| 3238 } else { | 3234 } else { |
| 3239 Register result = ToRegister(instr->result()); | 3235 Register result = ToRegister(instr->result()); |
| 3240 MemOperand mem_operand = PrepareKeyedOperand( | 3236 MemOperand mem_operand = PrepareKeyedOperand( |
| 3241 key, external_pointer, key_is_constant, constant_key, | 3237 key, external_pointer, key_is_constant, constant_key, |
| 3242 element_size_shift, shift_size, | 3238 element_size_shift, shift_size, |
| 3243 instr->additional_index(), additional_offset); | 3239 instr->additional_index(), additional_offset); |
| 3244 switch (elements_kind) { | 3240 switch (elements_kind) { |
| 3245 case EXTERNAL_BYTE_ELEMENTS: | 3241 case EXTERNAL_BYTE_ELEMENTS: |
| 3242 case INT8_ELEMENTS: |
| 3246 __ ldrsb(result, mem_operand); | 3243 __ ldrsb(result, mem_operand); |
| 3247 break; | 3244 break; |
| 3248 case EXTERNAL_PIXEL_ELEMENTS: | 3245 case EXTERNAL_PIXEL_ELEMENTS: |
| 3249 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3246 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 3247 case UINT8_ELEMENTS: |
| 3248 case UINT8_CLAMPED_ELEMENTS: |
| 3250 __ ldrb(result, mem_operand); | 3249 __ ldrb(result, mem_operand); |
| 3251 break; | 3250 break; |
| 3252 case EXTERNAL_SHORT_ELEMENTS: | 3251 case EXTERNAL_SHORT_ELEMENTS: |
| 3252 case INT16_ELEMENTS: |
| 3253 __ ldrsh(result, mem_operand); | 3253 __ ldrsh(result, mem_operand); |
| 3254 break; | 3254 break; |
| 3255 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3255 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 3256 case UINT16_ELEMENTS: |
| 3256 __ ldrh(result, mem_operand); | 3257 __ ldrh(result, mem_operand); |
| 3257 break; | 3258 break; |
| 3258 case EXTERNAL_INT_ELEMENTS: | 3259 case EXTERNAL_INT_ELEMENTS: |
| 3260 case INT32_ELEMENTS: |
| 3259 __ ldr(result, mem_operand); | 3261 __ ldr(result, mem_operand); |
| 3260 break; | 3262 break; |
| 3261 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3263 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 3264 case UINT32_ELEMENTS: |
| 3262 __ ldr(result, mem_operand); | 3265 __ ldr(result, mem_operand); |
| 3263 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { | 3266 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { |
| 3264 __ cmp(result, Operand(0x80000000)); | 3267 __ cmp(result, Operand(0x80000000)); |
| 3265 DeoptimizeIf(cs, instr->environment()); | 3268 DeoptimizeIf(cs, instr->environment()); |
| 3266 } | 3269 } |
| 3267 break; | 3270 break; |
| 3271 case FLOAT32_ELEMENTS: |
| 3272 case FLOAT64_ELEMENTS: |
| 3268 case EXTERNAL_FLOAT_ELEMENTS: | 3273 case EXTERNAL_FLOAT_ELEMENTS: |
| 3269 case EXTERNAL_DOUBLE_ELEMENTS: | 3274 case EXTERNAL_DOUBLE_ELEMENTS: |
| 3270 case FAST_HOLEY_DOUBLE_ELEMENTS: | 3275 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 3271 case FAST_HOLEY_ELEMENTS: | 3276 case FAST_HOLEY_ELEMENTS: |
| 3272 case FAST_HOLEY_SMI_ELEMENTS: | 3277 case FAST_HOLEY_SMI_ELEMENTS: |
| 3273 case FAST_DOUBLE_ELEMENTS: | 3278 case FAST_DOUBLE_ELEMENTS: |
| 3274 case FAST_ELEMENTS: | 3279 case FAST_ELEMENTS: |
| 3275 case FAST_SMI_ELEMENTS: | 3280 case FAST_SMI_ELEMENTS: |
| 3276 case DICTIONARY_ELEMENTS: | 3281 case DICTIONARY_ELEMENTS: |
| 3277 case NON_STRICT_ARGUMENTS_ELEMENTS: | 3282 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3355 } else { | 3360 } else { |
| 3356 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 3361 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); |
| 3357 __ cmp(result, scratch); | 3362 __ cmp(result, scratch); |
| 3358 DeoptimizeIf(eq, instr->environment()); | 3363 DeoptimizeIf(eq, instr->environment()); |
| 3359 } | 3364 } |
| 3360 } | 3365 } |
| 3361 } | 3366 } |
| 3362 | 3367 |
| 3363 | 3368 |
| 3364 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { | 3369 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { |
| 3365 if (instr->is_external()) { | 3370 if (instr->is_typed_elements()) { |
| 3366 DoLoadKeyedExternalArray(instr); | 3371 DoLoadKeyedExternalArray(instr); |
| 3367 } else if (instr->hydrogen()->representation().IsDouble()) { | 3372 } else if (instr->hydrogen()->representation().IsDouble()) { |
| 3368 DoLoadKeyedFixedDoubleArray(instr); | 3373 DoLoadKeyedFixedDoubleArray(instr); |
| 3369 } else { | 3374 } else { |
| 3370 DoLoadKeyedFixedArray(instr); | 3375 DoLoadKeyedFixedArray(instr); |
| 3371 } | 3376 } |
| 3372 } | 3377 } |
| 3373 | 3378 |
| 3374 | 3379 |
| 3375 MemOperand LCodeGen::PrepareKeyedOperand(Register key, | 3380 MemOperand LCodeGen::PrepareKeyedOperand(Register key, |
| 3376 Register base, | 3381 Register base, |
| 3377 bool key_is_constant, | 3382 bool key_is_constant, |
| 3378 int constant_key, | 3383 int constant_key, |
| 3379 int element_size, | 3384 int element_size, |
| 3380 int shift_size, | 3385 int shift_size, |
| 3381 int additional_index, | 3386 int additional_index, |
| 3382 int additional_offset) { | 3387 int additional_offset) { |
| 3383 if (additional_index != 0 && !key_is_constant) { | 3388 int base_offset = (additional_index << element_size) + additional_offset; |
| 3389 if (key_is_constant) { |
| 3390 return MemOperand(base, |
| 3391 base_offset + (constant_key << element_size)); |
| 3392 } |
| 3393 |
| 3394 if (additional_offset != 0) { |
| 3395 __ mov(scratch0(), Operand(base_offset)); |
| 3396 if (shift_size >= 0) { |
| 3397 __ add(scratch0(), scratch0(), Operand(key, LSL, shift_size)); |
| 3398 } else { |
| 3399 ASSERT_EQ(-1, shift_size); |
| 3400 __ add(scratch0(), scratch0(), Operand(key, LSR, 1)); |
| 3401 } |
| 3402 return MemOperand(base, scratch0()); |
| 3403 } |
| 3404 |
| 3405 if (additional_index != 0) { |
| 3384 additional_index *= 1 << (element_size - shift_size); | 3406 additional_index *= 1 << (element_size - shift_size); |
| 3385 __ add(scratch0(), key, Operand(additional_index)); | 3407 __ add(scratch0(), key, Operand(additional_index)); |
| 3386 } | 3408 } |
| 3387 | 3409 |
| 3388 if (key_is_constant) { | |
| 3389 return MemOperand(base, | |
| 3390 (constant_key << element_size) + additional_offset); | |
| 3391 } | |
| 3392 | |
| 3393 if (additional_index == 0) { | 3410 if (additional_index == 0) { |
| 3394 if (shift_size >= 0) { | 3411 if (shift_size >= 0) { |
| 3395 return MemOperand(base, key, LSL, shift_size); | 3412 return MemOperand(base, key, LSL, shift_size); |
| 3396 } else { | 3413 } else { |
| 3397 ASSERT_EQ(-1, shift_size); | 3414 ASSERT_EQ(-1, shift_size); |
| 3398 return MemOperand(base, key, LSR, 1); | 3415 return MemOperand(base, key, LSR, 1); |
| 3399 } | 3416 } |
| 3400 } | 3417 } |
| 3401 | 3418 |
| 3402 if (shift_size >= 0) { | 3419 if (shift_size >= 0) { |
| (...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4032 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4049 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 4033 } | 4050 } |
| 4034 | 4051 |
| 4035 | 4052 |
| 4036 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { | 4053 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { |
| 4037 ASSERT(ToRegister(instr->context()).is(cp)); | 4054 ASSERT(ToRegister(instr->context()).is(cp)); |
| 4038 ASSERT(ToRegister(instr->constructor()).is(r1)); | 4055 ASSERT(ToRegister(instr->constructor()).is(r1)); |
| 4039 ASSERT(ToRegister(instr->result()).is(r0)); | 4056 ASSERT(ToRegister(instr->result()).is(r0)); |
| 4040 | 4057 |
| 4041 __ mov(r0, Operand(instr->arity())); | 4058 __ mov(r0, Operand(instr->arity())); |
| 4042 __ mov(r2, Operand(instr->hydrogen()->property_cell())); | 4059 __ mov(r2, Operand(factory()->undefined_value())); |
| 4043 ElementsKind kind = instr->hydrogen()->elements_kind(); | 4060 ElementsKind kind = instr->hydrogen()->elements_kind(); |
| 4044 AllocationSiteOverrideMode override_mode = | 4061 AllocationSiteOverrideMode override_mode = |
| 4045 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) | 4062 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) |
| 4046 ? DISABLE_ALLOCATION_SITES | 4063 ? DISABLE_ALLOCATION_SITES |
| 4047 : DONT_OVERRIDE; | 4064 : DONT_OVERRIDE; |
| 4048 | 4065 |
| 4049 if (instr->arity() == 0) { | 4066 if (instr->arity() == 0) { |
| 4050 ArrayNoArgumentConstructorStub stub(kind, override_mode); | 4067 ArrayNoArgumentConstructorStub stub(kind, override_mode); |
| 4051 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4068 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 4052 } else if (instr->arity() == 1) { | 4069 } else if (instr->arity() == 1) { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4193 | 4210 |
| 4194 | 4211 |
| 4195 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 4212 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
| 4196 ASSERT(ToRegister(instr->context()).is(cp)); | 4213 ASSERT(ToRegister(instr->context()).is(cp)); |
| 4197 ASSERT(ToRegister(instr->object()).is(r1)); | 4214 ASSERT(ToRegister(instr->object()).is(r1)); |
| 4198 ASSERT(ToRegister(instr->value()).is(r0)); | 4215 ASSERT(ToRegister(instr->value()).is(r0)); |
| 4199 | 4216 |
| 4200 // Name is always in r2. | 4217 // Name is always in r2. |
| 4201 __ mov(r2, Operand(instr->name())); | 4218 __ mov(r2, Operand(instr->name())); |
| 4202 Handle<Code> ic = StoreIC::initialize_stub(isolate(), | 4219 Handle<Code> ic = StoreIC::initialize_stub(isolate(), |
| 4203 instr->strict_mode_flag(), | 4220 instr->strict_mode_flag()); |
| 4204 NOT_CONTEXTUAL); | |
| 4205 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); | 4221 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); |
| 4206 } | 4222 } |
| 4207 | 4223 |
| 4208 | 4224 |
| 4209 void LCodeGen::ApplyCheckIf(Condition condition, LBoundsCheck* check) { | 4225 void LCodeGen::ApplyCheckIf(Condition condition, LBoundsCheck* check) { |
| 4210 if (FLAG_debug_code && check->hydrogen()->skip_check()) { | 4226 if (FLAG_debug_code && check->hydrogen()->skip_check()) { |
| 4211 Label done; | 4227 Label done; |
| 4212 __ b(NegateCondition(condition), &done); | 4228 __ b(NegateCondition(condition), &done); |
| 4213 __ stop("eliminated bounds check failed"); | 4229 __ stop("eliminated bounds check failed"); |
| 4214 __ bind(&done); | 4230 __ bind(&done); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4248 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4264 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 4249 if (constant_key & 0xF0000000) { | 4265 if (constant_key & 0xF0000000) { |
| 4250 Abort(kArrayIndexConstantValueTooBig); | 4266 Abort(kArrayIndexConstantValueTooBig); |
| 4251 } | 4267 } |
| 4252 } else { | 4268 } else { |
| 4253 key = ToRegister(instr->key()); | 4269 key = ToRegister(instr->key()); |
| 4254 } | 4270 } |
| 4255 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4271 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 4256 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4272 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 4257 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4273 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4258 int additional_offset = instr->additional_index() << element_size_shift; | 4274 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) |
| 4275 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag |
| 4276 : 0; |
| 4259 | 4277 |
| 4260 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 4278 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 4261 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4279 elements_kind == FLOAT32_ELEMENTS || |
| 4280 elements_kind == EXTERNAL_DOUBLE_ELEMENTS || |
| 4281 elements_kind == FLOAT64_ELEMENTS) { |
| 4282 int base_offset = |
| 4283 (instr->additional_index() << element_size_shift) + additional_offset; |
| 4262 Register address = scratch0(); | 4284 Register address = scratch0(); |
| 4263 DwVfpRegister value(ToDoubleRegister(instr->value())); | 4285 DwVfpRegister value(ToDoubleRegister(instr->value())); |
| 4264 if (key_is_constant) { | 4286 if (key_is_constant) { |
| 4265 if (constant_key != 0) { | 4287 if (constant_key != 0) { |
| 4266 __ add(address, external_pointer, | 4288 __ add(address, external_pointer, |
| 4267 Operand(constant_key << element_size_shift)); | 4289 Operand(constant_key << element_size_shift)); |
| 4268 } else { | 4290 } else { |
| 4269 address = external_pointer; | 4291 address = external_pointer; |
| 4270 } | 4292 } |
| 4271 } else { | 4293 } else { |
| 4272 __ add(address, external_pointer, Operand(key, LSL, shift_size)); | 4294 __ add(address, external_pointer, Operand(key, LSL, shift_size)); |
| 4273 } | 4295 } |
| 4274 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4296 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| 4297 elements_kind == FLOAT32_ELEMENTS) { |
| 4275 __ vcvt_f32_f64(double_scratch0().low(), value); | 4298 __ vcvt_f32_f64(double_scratch0().low(), value); |
| 4276 __ vstr(double_scratch0().low(), address, additional_offset); | 4299 __ vstr(double_scratch0().low(), address, base_offset); |
| 4277 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 4300 } else { // Storing doubles, not floats. |
| 4278 __ vstr(value, address, additional_offset); | 4301 __ vstr(value, address, base_offset); |
| 4279 } | 4302 } |
| 4280 } else { | 4303 } else { |
| 4281 Register value(ToRegister(instr->value())); | 4304 Register value(ToRegister(instr->value())); |
| 4282 MemOperand mem_operand = PrepareKeyedOperand( | 4305 MemOperand mem_operand = PrepareKeyedOperand( |
| 4283 key, external_pointer, key_is_constant, constant_key, | 4306 key, external_pointer, key_is_constant, constant_key, |
| 4284 element_size_shift, shift_size, | 4307 element_size_shift, shift_size, |
| 4285 instr->additional_index(), additional_offset); | 4308 instr->additional_index(), additional_offset); |
| 4286 switch (elements_kind) { | 4309 switch (elements_kind) { |
| 4287 case EXTERNAL_PIXEL_ELEMENTS: | 4310 case EXTERNAL_PIXEL_ELEMENTS: |
| 4288 case EXTERNAL_BYTE_ELEMENTS: | 4311 case EXTERNAL_BYTE_ELEMENTS: |
| 4289 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 4312 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 4313 case UINT8_ELEMENTS: |
| 4314 case UINT8_CLAMPED_ELEMENTS: |
| 4315 case INT8_ELEMENTS: |
| 4290 __ strb(value, mem_operand); | 4316 __ strb(value, mem_operand); |
| 4291 break; | 4317 break; |
| 4292 case EXTERNAL_SHORT_ELEMENTS: | 4318 case EXTERNAL_SHORT_ELEMENTS: |
| 4293 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 4319 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 4320 case INT16_ELEMENTS: |
| 4321 case UINT16_ELEMENTS: |
| 4294 __ strh(value, mem_operand); | 4322 __ strh(value, mem_operand); |
| 4295 break; | 4323 break; |
| 4296 case EXTERNAL_INT_ELEMENTS: | 4324 case EXTERNAL_INT_ELEMENTS: |
| 4297 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 4325 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 4326 case INT32_ELEMENTS: |
| 4327 case UINT32_ELEMENTS: |
| 4298 __ str(value, mem_operand); | 4328 __ str(value, mem_operand); |
| 4299 break; | 4329 break; |
| 4330 case FLOAT32_ELEMENTS: |
| 4331 case FLOAT64_ELEMENTS: |
| 4300 case EXTERNAL_FLOAT_ELEMENTS: | 4332 case EXTERNAL_FLOAT_ELEMENTS: |
| 4301 case EXTERNAL_DOUBLE_ELEMENTS: | 4333 case EXTERNAL_DOUBLE_ELEMENTS: |
| 4302 case FAST_DOUBLE_ELEMENTS: | 4334 case FAST_DOUBLE_ELEMENTS: |
| 4303 case FAST_ELEMENTS: | 4335 case FAST_ELEMENTS: |
| 4304 case FAST_SMI_ELEMENTS: | 4336 case FAST_SMI_ELEMENTS: |
| 4305 case FAST_HOLEY_DOUBLE_ELEMENTS: | 4337 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 4306 case FAST_HOLEY_ELEMENTS: | 4338 case FAST_HOLEY_ELEMENTS: |
| 4307 case FAST_HOLEY_SMI_ELEMENTS: | 4339 case FAST_HOLEY_SMI_ELEMENTS: |
| 4308 case DICTIONARY_ELEMENTS: | 4340 case DICTIONARY_ELEMENTS: |
| 4309 case NON_STRICT_ARGUMENTS_ELEMENTS: | 4341 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4399 GetLinkRegisterState(), | 4431 GetLinkRegisterState(), |
| 4400 kSaveFPRegs, | 4432 kSaveFPRegs, |
| 4401 EMIT_REMEMBERED_SET, | 4433 EMIT_REMEMBERED_SET, |
| 4402 check_needed); | 4434 check_needed); |
| 4403 } | 4435 } |
| 4404 } | 4436 } |
| 4405 | 4437 |
| 4406 | 4438 |
| 4407 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { | 4439 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { |
| 4408 // By cases: external, fast double | 4440 // By cases: external, fast double |
| 4409 if (instr->is_external()) { | 4441 if (instr->is_typed_elements()) { |
| 4410 DoStoreKeyedExternalArray(instr); | 4442 DoStoreKeyedExternalArray(instr); |
| 4411 } else if (instr->hydrogen()->value()->representation().IsDouble()) { | 4443 } else if (instr->hydrogen()->value()->representation().IsDouble()) { |
| 4412 DoStoreKeyedFixedDoubleArray(instr); | 4444 DoStoreKeyedFixedDoubleArray(instr); |
| 4413 } else { | 4445 } else { |
| 4414 DoStoreKeyedFixedArray(instr); | 4446 DoStoreKeyedFixedArray(instr); |
| 4415 } | 4447 } |
| 4416 } | 4448 } |
| 4417 | 4449 |
| 4418 | 4450 |
| 4419 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 4451 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4470 Register temp = ToRegister(instr->temp()); | 4502 Register temp = ToRegister(instr->temp()); |
| 4471 Label no_memento_found; | 4503 Label no_memento_found; |
| 4472 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found); | 4504 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found); |
| 4473 DeoptimizeIf(eq, instr->environment()); | 4505 DeoptimizeIf(eq, instr->environment()); |
| 4474 __ bind(&no_memento_found); | 4506 __ bind(&no_memento_found); |
| 4475 } | 4507 } |
| 4476 | 4508 |
| 4477 | 4509 |
| 4478 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 4510 void LCodeGen::DoStringAdd(LStringAdd* instr) { |
| 4479 ASSERT(ToRegister(instr->context()).is(cp)); | 4511 ASSERT(ToRegister(instr->context()).is(cp)); |
| 4480 if (FLAG_new_string_add) { | 4512 ASSERT(ToRegister(instr->left()).is(r1)); |
| 4481 ASSERT(ToRegister(instr->left()).is(r1)); | 4513 ASSERT(ToRegister(instr->right()).is(r0)); |
| 4482 ASSERT(ToRegister(instr->right()).is(r0)); | 4514 StringAddStub stub(instr->hydrogen()->flags(), |
| 4483 NewStringAddStub stub(instr->hydrogen()->flags(), | 4515 isolate()->heap()->GetPretenureMode()); |
| 4484 isolate()->heap()->GetPretenureMode()); | 4516 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 4485 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 4486 } else { | |
| 4487 __ push(ToRegister(instr->left())); | |
| 4488 __ push(ToRegister(instr->right())); | |
| 4489 StringAddStub stub(instr->hydrogen()->flags()); | |
| 4490 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 4491 } | |
| 4492 } | 4517 } |
| 4493 | 4518 |
| 4494 | 4519 |
| 4495 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 4520 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
| 4496 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { | 4521 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { |
| 4497 public: | 4522 public: |
| 4498 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 4523 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
| 4499 : LDeferredCode(codegen), instr_(instr) { } | 4524 : LDeferredCode(codegen), instr_(instr) { } |
| 4500 virtual void Generate() V8_OVERRIDE { | 4525 virtual void Generate() V8_OVERRIDE { |
| 4501 codegen()->DoDeferredStringCharCodeAt(instr_); | 4526 codegen()->DoDeferredStringCharCodeAt(instr_); |
| (...skipping 1298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5800 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5825 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
| 5801 __ ldr(result, FieldMemOperand(scratch, | 5826 __ ldr(result, FieldMemOperand(scratch, |
| 5802 FixedArray::kHeaderSize - kPointerSize)); | 5827 FixedArray::kHeaderSize - kPointerSize)); |
| 5803 __ bind(&done); | 5828 __ bind(&done); |
| 5804 } | 5829 } |
| 5805 | 5830 |
| 5806 | 5831 |
| 5807 #undef __ | 5832 #undef __ |
| 5808 | 5833 |
| 5809 } } // namespace v8::internal | 5834 } } // namespace v8::internal |
| OLD | NEW |