| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/cpu-profiler.h" | 10 #include "src/cpu-profiler.h" |
| (...skipping 2289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2300 } | 2300 } |
| 2301 | 2301 |
| 2302 if (expected.Contains(ToBooleanStub::SYMBOL)) { | 2302 if (expected.Contains(ToBooleanStub::SYMBOL)) { |
| 2303 // Symbol value -> true. | 2303 // Symbol value -> true. |
| 2304 __ CompareInstanceType(map, ip, SYMBOL_TYPE); | 2304 __ CompareInstanceType(map, ip, SYMBOL_TYPE); |
| 2305 __ beq(instr->TrueLabel(chunk_)); | 2305 __ beq(instr->TrueLabel(chunk_)); |
| 2306 } | 2306 } |
| 2307 | 2307 |
| 2308 if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { | 2308 if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { |
| 2309 // SIMD value -> true. | 2309 // SIMD value -> true. |
| 2310 __ CompareInstanceType(map, ip, FLOAT32X4_TYPE); | 2310 Label not_simd; |
| 2311 __ beq(instr->TrueLabel(chunk_)); | 2311 __ CompareInstanceType(map, ip, FIRST_SIMD_VALUE_TYPE); |
| 2312 __ blt(¬_simd); |
| 2313 __ CompareInstanceType(map, ip, LAST_SIMD_VALUE_TYPE); |
| 2314 __ ble(instr->TrueLabel(chunk_)); |
| 2315 __ bind(¬_simd); |
| 2312 } | 2316 } |
| 2313 | 2317 |
| 2314 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 2318 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { |
| 2315 // heap number -> false iff +0, -0, or NaN. | 2319 // heap number -> false iff +0, -0, or NaN. |
| 2316 Label not_heap_number; | 2320 Label not_heap_number; |
| 2317 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); | 2321 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); |
| 2318 __ bne(¬_heap_number); | 2322 __ bne(¬_heap_number); |
| 2319 __ lfd(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); | 2323 __ lfd(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
| 2320 // Test the double value. Zero and NaN are false. | 2324 // Test the double value. Zero and NaN are false. |
| 2321 __ fcmpu(dbl_scratch, kDoubleRegZero, cr7); | 2325 __ fcmpu(dbl_scratch, kDoubleRegZero, cr7); |
| (...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3057 CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(), | 3061 CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(), |
| 3058 SLOPPY, PREMONOMORPHIC).code(); | 3062 SLOPPY, PREMONOMORPHIC).code(); |
| 3059 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3063 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3060 } | 3064 } |
| 3061 | 3065 |
| 3062 | 3066 |
| 3063 void LCodeGen::DoLoadGlobalViaContext(LLoadGlobalViaContext* instr) { | 3067 void LCodeGen::DoLoadGlobalViaContext(LLoadGlobalViaContext* instr) { |
| 3064 DCHECK(ToRegister(instr->context()).is(cp)); | 3068 DCHECK(ToRegister(instr->context()).is(cp)); |
| 3065 DCHECK(ToRegister(instr->result()).is(r3)); | 3069 DCHECK(ToRegister(instr->result()).is(r3)); |
| 3066 | 3070 |
| 3067 int const slot = instr->slot_index(); | 3071 __ mov(LoadGlobalViaContextDescriptor::DepthRegister(), |
| 3068 int const depth = instr->depth(); | 3072 Operand(Smi::FromInt(instr->depth()))); |
| 3069 if (depth <= LoadGlobalViaContextStub::kMaximumDepth) { | 3073 __ mov(LoadGlobalViaContextDescriptor::SlotRegister(), |
| 3070 __ mov(LoadGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); | 3074 Operand(Smi::FromInt(instr->slot_index()))); |
| 3071 Handle<Code> stub = | 3075 __ mov(LoadGlobalViaContextDescriptor::NameRegister(), |
| 3072 CodeFactory::LoadGlobalViaContext(isolate(), depth).code(); | 3076 Operand(instr->name())); |
| 3073 CallCode(stub, RelocInfo::CODE_TARGET, instr); | 3077 |
| 3074 } else { | 3078 Handle<Code> stub = |
| 3075 __ Push(Smi::FromInt(slot)); | 3079 CodeFactory::LoadGlobalViaContext(isolate(), instr->depth()).code(); |
| 3076 __ CallRuntime(Runtime::kLoadGlobalViaContext, 1); | 3080 CallCode(stub, RelocInfo::CODE_TARGET, instr); |
| 3077 } | |
| 3078 } | 3081 } |
| 3079 | 3082 |
| 3080 | 3083 |
| 3081 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 3084 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
| 3082 Register context = ToRegister(instr->context()); | 3085 Register context = ToRegister(instr->context()); |
| 3083 Register result = ToRegister(instr->result()); | 3086 Register result = ToRegister(instr->result()); |
| 3084 __ LoadP(result, ContextOperand(context, instr->slot_index())); | 3087 __ LoadP(result, ContextOperand(context, instr->slot_index())); |
| 3085 if (instr->hydrogen()->RequiresHoleCheck()) { | 3088 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3086 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 3089 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 3087 if (instr->hydrogen()->DeoptimizesOnHole()) { | 3090 if (instr->hydrogen()->DeoptimizesOnHole()) { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3287 if (constant_key & 0xF0000000) { | 3290 if (constant_key & 0xF0000000) { |
| 3288 Abort(kArrayIndexConstantValueTooBig); | 3291 Abort(kArrayIndexConstantValueTooBig); |
| 3289 } | 3292 } |
| 3290 } else { | 3293 } else { |
| 3291 key = ToRegister(instr->key()); | 3294 key = ToRegister(instr->key()); |
| 3292 } | 3295 } |
| 3293 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3296 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 3294 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); | 3297 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); |
| 3295 int base_offset = instr->base_offset(); | 3298 int base_offset = instr->base_offset(); |
| 3296 | 3299 |
| 3297 if (elements_kind == FLOAT32_ELEMENTS || elements_kind == FLOAT64_ELEMENTS) { | 3300 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 3301 elements_kind == FLOAT32_ELEMENTS || |
| 3302 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
| 3303 elements_kind == FLOAT64_ELEMENTS) { |
| 3298 DoubleRegister result = ToDoubleRegister(instr->result()); | 3304 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3299 if (key_is_constant) { | 3305 if (key_is_constant) { |
| 3300 __ Add(scratch0(), external_pointer, constant_key << element_size_shift, | 3306 __ Add(scratch0(), external_pointer, constant_key << element_size_shift, |
| 3301 r0); | 3307 r0); |
| 3302 } else { | 3308 } else { |
| 3303 __ IndexToArrayOffset(r0, key, element_size_shift, key_is_smi); | 3309 __ IndexToArrayOffset(r0, key, element_size_shift, key_is_smi); |
| 3304 __ add(scratch0(), external_pointer, r0); | 3310 __ add(scratch0(), external_pointer, r0); |
| 3305 } | 3311 } |
| 3306 if (elements_kind == FLOAT32_ELEMENTS) { | 3312 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 3313 elements_kind == FLOAT32_ELEMENTS) { |
| 3307 __ lfs(result, MemOperand(scratch0(), base_offset)); | 3314 __ lfs(result, MemOperand(scratch0(), base_offset)); |
| 3308 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 3315 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
| 3309 __ lfd(result, MemOperand(scratch0(), base_offset)); | 3316 __ lfd(result, MemOperand(scratch0(), base_offset)); |
| 3310 } | 3317 } |
| 3311 } else { | 3318 } else { |
| 3312 Register result = ToRegister(instr->result()); | 3319 Register result = ToRegister(instr->result()); |
| 3313 MemOperand mem_operand = | 3320 MemOperand mem_operand = |
| 3314 PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi, | 3321 PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi, |
| 3315 constant_key, element_size_shift, base_offset); | 3322 constant_key, element_size_shift, base_offset); |
| 3316 switch (elements_kind) { | 3323 switch (elements_kind) { |
| 3324 case EXTERNAL_INT8_ELEMENTS: |
| 3317 case INT8_ELEMENTS: | 3325 case INT8_ELEMENTS: |
| 3318 if (key_is_constant) { | 3326 if (key_is_constant) { |
| 3319 __ LoadByte(result, mem_operand, r0); | 3327 __ LoadByte(result, mem_operand, r0); |
| 3320 } else { | 3328 } else { |
| 3321 __ lbzx(result, mem_operand); | 3329 __ lbzx(result, mem_operand); |
| 3322 } | 3330 } |
| 3323 __ extsb(result, result); | 3331 __ extsb(result, result); |
| 3324 break; | 3332 break; |
| 3333 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: |
| 3334 case EXTERNAL_UINT8_ELEMENTS: |
| 3325 case UINT8_ELEMENTS: | 3335 case UINT8_ELEMENTS: |
| 3326 case UINT8_CLAMPED_ELEMENTS: | 3336 case UINT8_CLAMPED_ELEMENTS: |
| 3327 if (key_is_constant) { | 3337 if (key_is_constant) { |
| 3328 __ LoadByte(result, mem_operand, r0); | 3338 __ LoadByte(result, mem_operand, r0); |
| 3329 } else { | 3339 } else { |
| 3330 __ lbzx(result, mem_operand); | 3340 __ lbzx(result, mem_operand); |
| 3331 } | 3341 } |
| 3332 break; | 3342 break; |
| 3343 case EXTERNAL_INT16_ELEMENTS: |
| 3333 case INT16_ELEMENTS: | 3344 case INT16_ELEMENTS: |
| 3334 if (key_is_constant) { | 3345 if (key_is_constant) { |
| 3335 __ LoadHalfWordArith(result, mem_operand, r0); | 3346 __ LoadHalfWordArith(result, mem_operand, r0); |
| 3336 } else { | 3347 } else { |
| 3337 __ lhax(result, mem_operand); | 3348 __ lhax(result, mem_operand); |
| 3338 } | 3349 } |
| 3339 break; | 3350 break; |
| 3351 case EXTERNAL_UINT16_ELEMENTS: |
| 3340 case UINT16_ELEMENTS: | 3352 case UINT16_ELEMENTS: |
| 3341 if (key_is_constant) { | 3353 if (key_is_constant) { |
| 3342 __ LoadHalfWord(result, mem_operand, r0); | 3354 __ LoadHalfWord(result, mem_operand, r0); |
| 3343 } else { | 3355 } else { |
| 3344 __ lhzx(result, mem_operand); | 3356 __ lhzx(result, mem_operand); |
| 3345 } | 3357 } |
| 3346 break; | 3358 break; |
| 3359 case EXTERNAL_INT32_ELEMENTS: |
| 3347 case INT32_ELEMENTS: | 3360 case INT32_ELEMENTS: |
| 3348 if (key_is_constant) { | 3361 if (key_is_constant) { |
| 3349 __ LoadWordArith(result, mem_operand, r0); | 3362 __ LoadWordArith(result, mem_operand, r0); |
| 3350 } else { | 3363 } else { |
| 3351 __ lwax(result, mem_operand); | 3364 __ lwax(result, mem_operand); |
| 3352 } | 3365 } |
| 3353 break; | 3366 break; |
| 3367 case EXTERNAL_UINT32_ELEMENTS: |
| 3354 case UINT32_ELEMENTS: | 3368 case UINT32_ELEMENTS: |
| 3355 if (key_is_constant) { | 3369 if (key_is_constant) { |
| 3356 __ LoadWord(result, mem_operand, r0); | 3370 __ LoadWord(result, mem_operand, r0); |
| 3357 } else { | 3371 } else { |
| 3358 __ lwzx(result, mem_operand); | 3372 __ lwzx(result, mem_operand); |
| 3359 } | 3373 } |
| 3360 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { | 3374 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { |
| 3361 __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); | 3375 __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); |
| 3362 __ cmplw(result, r0); | 3376 __ cmplw(result, r0); |
| 3363 DeoptimizeIf(ge, instr, Deoptimizer::kNegativeValue); | 3377 DeoptimizeIf(ge, instr, Deoptimizer::kNegativeValue); |
| 3364 } | 3378 } |
| 3365 break; | 3379 break; |
| 3366 case FLOAT32_ELEMENTS: | 3380 case FLOAT32_ELEMENTS: |
| 3367 case FLOAT64_ELEMENTS: | 3381 case FLOAT64_ELEMENTS: |
| 3382 case EXTERNAL_FLOAT32_ELEMENTS: |
| 3383 case EXTERNAL_FLOAT64_ELEMENTS: |
| 3368 case FAST_HOLEY_DOUBLE_ELEMENTS: | 3384 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 3369 case FAST_HOLEY_ELEMENTS: | 3385 case FAST_HOLEY_ELEMENTS: |
| 3370 case FAST_HOLEY_SMI_ELEMENTS: | 3386 case FAST_HOLEY_SMI_ELEMENTS: |
| 3371 case FAST_DOUBLE_ELEMENTS: | 3387 case FAST_DOUBLE_ELEMENTS: |
| 3372 case FAST_ELEMENTS: | 3388 case FAST_ELEMENTS: |
| 3373 case FAST_SMI_ELEMENTS: | 3389 case FAST_SMI_ELEMENTS: |
| 3374 case DICTIONARY_ELEMENTS: | 3390 case DICTIONARY_ELEMENTS: |
| 3375 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 3391 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 3376 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 3392 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
| 3377 UNREACHABLE(); | 3393 UNREACHABLE(); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3494 __ CmpSmiLiteral(result, Smi::FromInt(Isolate::kArrayProtectorValid), r0); | 3510 __ CmpSmiLiteral(result, Smi::FromInt(Isolate::kArrayProtectorValid), r0); |
| 3495 DeoptimizeIf(ne, instr, Deoptimizer::kHole); | 3511 DeoptimizeIf(ne, instr, Deoptimizer::kHole); |
| 3496 } | 3512 } |
| 3497 __ LoadRoot(result, Heap::kUndefinedValueRootIndex); | 3513 __ LoadRoot(result, Heap::kUndefinedValueRootIndex); |
| 3498 __ bind(&done); | 3514 __ bind(&done); |
| 3499 } | 3515 } |
| 3500 } | 3516 } |
| 3501 | 3517 |
| 3502 | 3518 |
| 3503 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { | 3519 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { |
| 3504 if (instr->is_fixed_typed_array()) { | 3520 if (instr->is_typed_elements()) { |
| 3505 DoLoadKeyedExternalArray(instr); | 3521 DoLoadKeyedExternalArray(instr); |
| 3506 } else if (instr->hydrogen()->representation().IsDouble()) { | 3522 } else if (instr->hydrogen()->representation().IsDouble()) { |
| 3507 DoLoadKeyedFixedDoubleArray(instr); | 3523 DoLoadKeyedFixedDoubleArray(instr); |
| 3508 } else { | 3524 } else { |
| 3509 DoLoadKeyedFixedArray(instr); | 3525 DoLoadKeyedFixedArray(instr); |
| 3510 } | 3526 } |
| 3511 } | 3527 } |
| 3512 | 3528 |
| 3513 | 3529 |
| 3514 MemOperand LCodeGen::PrepareKeyedOperand(Register key, Register base, | 3530 MemOperand LCodeGen::PrepareKeyedOperand(Register key, Register base, |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3755 __ LoadP(result, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3771 __ LoadP(result, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3756 } else { | 3772 } else { |
| 3757 // If there is no frame, the context must be in cp. | 3773 // If there is no frame, the context must be in cp. |
| 3758 DCHECK(result.is(cp)); | 3774 DCHECK(result.is(cp)); |
| 3759 } | 3775 } |
| 3760 } | 3776 } |
| 3761 | 3777 |
| 3762 | 3778 |
| 3763 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { | 3779 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { |
| 3764 DCHECK(ToRegister(instr->context()).is(cp)); | 3780 DCHECK(ToRegister(instr->context()).is(cp)); |
| 3781 __ push(cp); // The context is the first argument. |
| 3765 __ Move(scratch0(), instr->hydrogen()->pairs()); | 3782 __ Move(scratch0(), instr->hydrogen()->pairs()); |
| 3766 __ push(scratch0()); | 3783 __ push(scratch0()); |
| 3767 __ LoadSmiLiteral(scratch0(), Smi::FromInt(instr->hydrogen()->flags())); | 3784 __ LoadSmiLiteral(scratch0(), Smi::FromInt(instr->hydrogen()->flags())); |
| 3768 __ push(scratch0()); | 3785 __ push(scratch0()); |
| 3769 CallRuntime(Runtime::kDeclareGlobals, 2, instr); | 3786 CallRuntime(Runtime::kDeclareGlobals, 3, instr); |
| 3770 } | 3787 } |
| 3771 | 3788 |
| 3772 | 3789 |
| 3773 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 3790 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
| 3774 int formal_parameter_count, int arity, | 3791 int formal_parameter_count, int arity, |
| 3775 LInstruction* instr) { | 3792 LInstruction* instr) { |
| 3776 bool dont_adapt_arguments = | 3793 bool dont_adapt_arguments = |
| 3777 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 3794 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
| 3778 bool can_invoke_directly = | 3795 bool can_invoke_directly = |
| 3779 dont_adapt_arguments || formal_parameter_count == arity; | 3796 dont_adapt_arguments || formal_parameter_count == arity; |
| (...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4465 instr->hydrogen()->initialization_state()).code(); | 4482 instr->hydrogen()->initialization_state()).code(); |
| 4466 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 4483 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 4467 } | 4484 } |
| 4468 | 4485 |
| 4469 | 4486 |
| 4470 void LCodeGen::DoStoreGlobalViaContext(LStoreGlobalViaContext* instr) { | 4487 void LCodeGen::DoStoreGlobalViaContext(LStoreGlobalViaContext* instr) { |
| 4471 DCHECK(ToRegister(instr->context()).is(cp)); | 4488 DCHECK(ToRegister(instr->context()).is(cp)); |
| 4472 DCHECK(ToRegister(instr->value()) | 4489 DCHECK(ToRegister(instr->value()) |
| 4473 .is(StoreGlobalViaContextDescriptor::ValueRegister())); | 4490 .is(StoreGlobalViaContextDescriptor::ValueRegister())); |
| 4474 | 4491 |
| 4475 int const slot = instr->slot_index(); | 4492 __ mov(StoreGlobalViaContextDescriptor::DepthRegister(), |
| 4476 int const depth = instr->depth(); | 4493 Operand(Smi::FromInt(instr->depth()))); |
| 4477 if (depth <= StoreGlobalViaContextStub::kMaximumDepth) { | 4494 __ mov(StoreGlobalViaContextDescriptor::SlotRegister(), |
| 4478 __ mov(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); | 4495 Operand(Smi::FromInt(instr->slot_index()))); |
| 4479 Handle<Code> stub = CodeFactory::StoreGlobalViaContext( | 4496 __ mov(StoreGlobalViaContextDescriptor::NameRegister(), |
| 4480 isolate(), depth, instr->language_mode()).code(); | 4497 Operand(instr->name())); |
| 4481 CallCode(stub, RelocInfo::CODE_TARGET, instr); | 4498 |
| 4482 } else { | 4499 Handle<Code> stub = CodeFactory::StoreGlobalViaContext( |
| 4483 __ Push(Smi::FromInt(slot)); | 4500 isolate(), instr->depth(), instr->language_mode()) |
| 4484 __ push(StoreGlobalViaContextDescriptor::ValueRegister()); | 4501 .code(); |
| 4485 __ CallRuntime(is_strict(instr->language_mode()) | 4502 CallCode(stub, RelocInfo::CODE_TARGET, instr); |
| 4486 ? Runtime::kStoreGlobalViaContext_Strict | |
| 4487 : Runtime::kStoreGlobalViaContext_Sloppy, | |
| 4488 2); | |
| 4489 } | |
| 4490 } | 4503 } |
| 4491 | 4504 |
| 4492 | 4505 |
| 4493 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { | 4506 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
| 4494 Representation representation = instr->hydrogen()->length()->representation(); | 4507 Representation representation = instr->hydrogen()->length()->representation(); |
| 4495 DCHECK(representation.Equals(instr->hydrogen()->index()->representation())); | 4508 DCHECK(representation.Equals(instr->hydrogen()->index()->representation())); |
| 4496 DCHECK(representation.IsSmiOrInteger32()); | 4509 DCHECK(representation.IsSmiOrInteger32()); |
| 4497 | 4510 |
| 4498 Condition cc = instr->hydrogen()->allow_equality() ? lt : le; | 4511 Condition cc = instr->hydrogen()->allow_equality() ? lt : le; |
| 4499 if (instr->length()->IsConstantOperand()) { | 4512 if (instr->length()->IsConstantOperand()) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4544 if (constant_key & 0xF0000000) { | 4557 if (constant_key & 0xF0000000) { |
| 4545 Abort(kArrayIndexConstantValueTooBig); | 4558 Abort(kArrayIndexConstantValueTooBig); |
| 4546 } | 4559 } |
| 4547 } else { | 4560 } else { |
| 4548 key = ToRegister(instr->key()); | 4561 key = ToRegister(instr->key()); |
| 4549 } | 4562 } |
| 4550 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4563 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 4551 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); | 4564 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); |
| 4552 int base_offset = instr->base_offset(); | 4565 int base_offset = instr->base_offset(); |
| 4553 | 4566 |
| 4554 if (elements_kind == FLOAT32_ELEMENTS || elements_kind == FLOAT64_ELEMENTS) { | 4567 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 4568 elements_kind == FLOAT32_ELEMENTS || |
| 4569 elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
| 4570 elements_kind == FLOAT64_ELEMENTS) { |
| 4555 Register address = scratch0(); | 4571 Register address = scratch0(); |
| 4556 DoubleRegister value(ToDoubleRegister(instr->value())); | 4572 DoubleRegister value(ToDoubleRegister(instr->value())); |
| 4557 if (key_is_constant) { | 4573 if (key_is_constant) { |
| 4558 if (constant_key != 0) { | 4574 if (constant_key != 0) { |
| 4559 __ Add(address, external_pointer, constant_key << element_size_shift, | 4575 __ Add(address, external_pointer, constant_key << element_size_shift, |
| 4560 r0); | 4576 r0); |
| 4561 } else { | 4577 } else { |
| 4562 address = external_pointer; | 4578 address = external_pointer; |
| 4563 } | 4579 } |
| 4564 } else { | 4580 } else { |
| 4565 __ IndexToArrayOffset(r0, key, element_size_shift, key_is_smi); | 4581 __ IndexToArrayOffset(r0, key, element_size_shift, key_is_smi); |
| 4566 __ add(address, external_pointer, r0); | 4582 __ add(address, external_pointer, r0); |
| 4567 } | 4583 } |
| 4568 if (elements_kind == FLOAT32_ELEMENTS) { | 4584 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 4585 elements_kind == FLOAT32_ELEMENTS) { |
| 4569 __ frsp(double_scratch0(), value); | 4586 __ frsp(double_scratch0(), value); |
| 4570 __ stfs(double_scratch0(), MemOperand(address, base_offset)); | 4587 __ stfs(double_scratch0(), MemOperand(address, base_offset)); |
| 4571 } else { // Storing doubles, not floats. | 4588 } else { // Storing doubles, not floats. |
| 4572 __ stfd(value, MemOperand(address, base_offset)); | 4589 __ stfd(value, MemOperand(address, base_offset)); |
| 4573 } | 4590 } |
| 4574 } else { | 4591 } else { |
| 4575 Register value(ToRegister(instr->value())); | 4592 Register value(ToRegister(instr->value())); |
| 4576 MemOperand mem_operand = | 4593 MemOperand mem_operand = |
| 4577 PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi, | 4594 PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi, |
| 4578 constant_key, element_size_shift, base_offset); | 4595 constant_key, element_size_shift, base_offset); |
| 4579 switch (elements_kind) { | 4596 switch (elements_kind) { |
| 4597 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: |
| 4598 case EXTERNAL_INT8_ELEMENTS: |
| 4599 case EXTERNAL_UINT8_ELEMENTS: |
| 4580 case UINT8_ELEMENTS: | 4600 case UINT8_ELEMENTS: |
| 4581 case UINT8_CLAMPED_ELEMENTS: | 4601 case UINT8_CLAMPED_ELEMENTS: |
| 4582 case INT8_ELEMENTS: | 4602 case INT8_ELEMENTS: |
| 4583 if (key_is_constant) { | 4603 if (key_is_constant) { |
| 4584 __ StoreByte(value, mem_operand, r0); | 4604 __ StoreByte(value, mem_operand, r0); |
| 4585 } else { | 4605 } else { |
| 4586 __ stbx(value, mem_operand); | 4606 __ stbx(value, mem_operand); |
| 4587 } | 4607 } |
| 4588 break; | 4608 break; |
| 4609 case EXTERNAL_INT16_ELEMENTS: |
| 4610 case EXTERNAL_UINT16_ELEMENTS: |
| 4589 case INT16_ELEMENTS: | 4611 case INT16_ELEMENTS: |
| 4590 case UINT16_ELEMENTS: | 4612 case UINT16_ELEMENTS: |
| 4591 if (key_is_constant) { | 4613 if (key_is_constant) { |
| 4592 __ StoreHalfWord(value, mem_operand, r0); | 4614 __ StoreHalfWord(value, mem_operand, r0); |
| 4593 } else { | 4615 } else { |
| 4594 __ sthx(value, mem_operand); | 4616 __ sthx(value, mem_operand); |
| 4595 } | 4617 } |
| 4596 break; | 4618 break; |
| 4619 case EXTERNAL_INT32_ELEMENTS: |
| 4620 case EXTERNAL_UINT32_ELEMENTS: |
| 4597 case INT32_ELEMENTS: | 4621 case INT32_ELEMENTS: |
| 4598 case UINT32_ELEMENTS: | 4622 case UINT32_ELEMENTS: |
| 4599 if (key_is_constant) { | 4623 if (key_is_constant) { |
| 4600 __ StoreWord(value, mem_operand, r0); | 4624 __ StoreWord(value, mem_operand, r0); |
| 4601 } else { | 4625 } else { |
| 4602 __ stwx(value, mem_operand); | 4626 __ stwx(value, mem_operand); |
| 4603 } | 4627 } |
| 4604 break; | 4628 break; |
| 4605 case FLOAT32_ELEMENTS: | 4629 case FLOAT32_ELEMENTS: |
| 4606 case FLOAT64_ELEMENTS: | 4630 case FLOAT64_ELEMENTS: |
| 4631 case EXTERNAL_FLOAT32_ELEMENTS: |
| 4632 case EXTERNAL_FLOAT64_ELEMENTS: |
| 4607 case FAST_DOUBLE_ELEMENTS: | 4633 case FAST_DOUBLE_ELEMENTS: |
| 4608 case FAST_ELEMENTS: | 4634 case FAST_ELEMENTS: |
| 4609 case FAST_SMI_ELEMENTS: | 4635 case FAST_SMI_ELEMENTS: |
| 4610 case FAST_HOLEY_DOUBLE_ELEMENTS: | 4636 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 4611 case FAST_HOLEY_ELEMENTS: | 4637 case FAST_HOLEY_ELEMENTS: |
| 4612 case FAST_HOLEY_SMI_ELEMENTS: | 4638 case FAST_HOLEY_SMI_ELEMENTS: |
| 4613 case DICTIONARY_ELEMENTS: | 4639 case DICTIONARY_ELEMENTS: |
| 4614 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: | 4640 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: |
| 4615 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: | 4641 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: |
| 4616 UNREACHABLE(); | 4642 UNREACHABLE(); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4714 __ Add(key, store_base, offset, r0); | 4740 __ Add(key, store_base, offset, r0); |
| 4715 __ RecordWrite(elements, key, value, GetLinkRegisterState(), kSaveFPRegs, | 4741 __ RecordWrite(elements, key, value, GetLinkRegisterState(), kSaveFPRegs, |
| 4716 EMIT_REMEMBERED_SET, check_needed, | 4742 EMIT_REMEMBERED_SET, check_needed, |
| 4717 hinstr->PointersToHereCheckForValue()); | 4743 hinstr->PointersToHereCheckForValue()); |
| 4718 } | 4744 } |
| 4719 } | 4745 } |
| 4720 | 4746 |
| 4721 | 4747 |
| 4722 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { | 4748 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { |
| 4723 // By cases: external, fast double | 4749 // By cases: external, fast double |
| 4724 if (instr->is_fixed_typed_array()) { | 4750 if (instr->is_typed_elements()) { |
| 4725 DoStoreKeyedExternalArray(instr); | 4751 DoStoreKeyedExternalArray(instr); |
| 4726 } else if (instr->hydrogen()->value()->representation().IsDouble()) { | 4752 } else if (instr->hydrogen()->value()->representation().IsDouble()) { |
| 4727 DoStoreKeyedFixedDoubleArray(instr); | 4753 DoStoreKeyedFixedDoubleArray(instr); |
| 4728 } else { | 4754 } else { |
| 4729 DoStoreKeyedFixedArray(instr); | 4755 DoStoreKeyedFixedArray(instr); |
| 4730 } | 4756 } |
| 4731 } | 4757 } |
| 4732 | 4758 |
| 4733 | 4759 |
| 4734 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 4760 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
| (...skipping 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5985 __ lbz(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); | 6011 __ lbz(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); |
| 5986 __ ExtractBit(r0, scratch, Map::kIsUndetectable); | 6012 __ ExtractBit(r0, scratch, Map::kIsUndetectable); |
| 5987 __ cmpi(r0, Operand::Zero()); | 6013 __ cmpi(r0, Operand::Zero()); |
| 5988 final_branch_condition = eq; | 6014 final_branch_condition = eq; |
| 5989 | 6015 |
| 5990 } else if (String::Equals(type_name, factory->float32x4_string())) { | 6016 } else if (String::Equals(type_name, factory->float32x4_string())) { |
| 5991 __ JumpIfSmi(input, false_label); | 6017 __ JumpIfSmi(input, false_label); |
| 5992 __ CompareObjectType(input, scratch, no_reg, FLOAT32X4_TYPE); | 6018 __ CompareObjectType(input, scratch, no_reg, FLOAT32X4_TYPE); |
| 5993 final_branch_condition = eq; | 6019 final_branch_condition = eq; |
| 5994 | 6020 |
| 6021 } else if (String::Equals(type_name, factory->int32x4_string())) { |
| 6022 __ JumpIfSmi(input, false_label); |
| 6023 __ CompareObjectType(input, scratch, no_reg, INT32X4_TYPE); |
| 6024 final_branch_condition = eq; |
| 6025 |
| 6026 } else if (String::Equals(type_name, factory->bool32x4_string())) { |
| 6027 __ JumpIfSmi(input, false_label); |
| 6028 __ CompareObjectType(input, scratch, no_reg, BOOL32X4_TYPE); |
| 6029 final_branch_condition = eq; |
| 6030 |
| 6031 } else if (String::Equals(type_name, factory->int16x8_string())) { |
| 6032 __ JumpIfSmi(input, false_label); |
| 6033 __ CompareObjectType(input, scratch, no_reg, INT16X8_TYPE); |
| 6034 final_branch_condition = eq; |
| 6035 |
| 6036 } else if (String::Equals(type_name, factory->bool16x8_string())) { |
| 6037 __ JumpIfSmi(input, false_label); |
| 6038 __ CompareObjectType(input, scratch, no_reg, BOOL16X8_TYPE); |
| 6039 final_branch_condition = eq; |
| 6040 |
| 6041 } else if (String::Equals(type_name, factory->int8x16_string())) { |
| 6042 __ JumpIfSmi(input, false_label); |
| 6043 __ CompareObjectType(input, scratch, no_reg, INT8X16_TYPE); |
| 6044 final_branch_condition = eq; |
| 6045 |
| 6046 } else if (String::Equals(type_name, factory->bool8x16_string())) { |
| 6047 __ JumpIfSmi(input, false_label); |
| 6048 __ CompareObjectType(input, scratch, no_reg, BOOL8X16_TYPE); |
| 6049 final_branch_condition = eq; |
| 6050 |
| 5995 } else { | 6051 } else { |
| 5996 __ b(false_label); | 6052 __ b(false_label); |
| 5997 } | 6053 } |
| 5998 | 6054 |
| 5999 return final_branch_condition; | 6055 return final_branch_condition; |
| 6000 } | 6056 } |
| 6001 | 6057 |
| 6002 | 6058 |
| 6003 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 6059 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
| 6004 Register temp1 = ToRegister(instr->temp()); | 6060 Register temp1 = ToRegister(instr->temp()); |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6292 __ Push(scope_info); | 6348 __ Push(scope_info); |
| 6293 __ push(ToRegister(instr->function())); | 6349 __ push(ToRegister(instr->function())); |
| 6294 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6350 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 6295 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6351 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 6296 } | 6352 } |
| 6297 | 6353 |
| 6298 | 6354 |
| 6299 #undef __ | 6355 #undef __ |
| 6300 } // namespace internal | 6356 } // namespace internal |
| 6301 } // namespace v8 | 6357 } // namespace v8 |
| OLD | NEW |