| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 | 459 |
| 460 ASSERT(ToRegister(instr->result()).is(x0)); | 460 ASSERT(ToRegister(instr->result()).is(x0)); |
| 461 } | 461 } |
| 462 | 462 |
| 463 | 463 |
| 464 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { | 464 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { |
| 465 ASSERT(instr->IsMarkedAsCall()); | 465 ASSERT(instr->IsMarkedAsCall()); |
| 466 ASSERT(ToRegister(instr->constructor()).is(x1)); | 466 ASSERT(ToRegister(instr->constructor()).is(x1)); |
| 467 | 467 |
| 468 __ Mov(x0, Operand(instr->arity())); | 468 __ Mov(x0, Operand(instr->arity())); |
| 469 __ Mov(x2, Operand(instr->hydrogen()->property_cell())); | 469 __ Mov(x2, Operand(factory()->undefined_value())); |
| 470 | 470 |
| 471 ElementsKind kind = instr->hydrogen()->elements_kind(); | 471 ElementsKind kind = instr->hydrogen()->elements_kind(); |
| 472 AllocationSiteOverrideMode override_mode = | 472 AllocationSiteOverrideMode override_mode = |
| 473 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) | 473 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) |
| 474 ? DISABLE_ALLOCATION_SITES | 474 ? DISABLE_ALLOCATION_SITES |
| 475 : DONT_OVERRIDE; | 475 : DONT_OVERRIDE; |
| 476 | 476 |
| 477 if (instr->arity() == 0) { | 477 if (instr->arity() == 0) { |
| 478 ArrayNoArgumentConstructorStub stub(kind, override_mode); | 478 ArrayNoArgumentConstructorStub stub(kind, override_mode); |
| 479 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 479 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 | 693 |
| 694 if (info()->saves_caller_doubles()) { | 694 if (info()->saves_caller_doubles()) { |
| 695 SaveCallerDoubles(); | 695 SaveCallerDoubles(); |
| 696 } | 696 } |
| 697 | 697 |
| 698 // Allocate a local context if needed. | 698 // Allocate a local context if needed. |
| 699 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 699 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 700 if (heap_slots > 0) { | 700 if (heap_slots > 0) { |
| 701 Comment(";;; Allocate local context"); | 701 Comment(";;; Allocate local context"); |
| 702 // Argument to NewContext is the function, which is in x1. | 702 // Argument to NewContext is the function, which is in x1. |
| 703 __ Push(x1); | |
| 704 if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 703 if (heap_slots <= FastNewContextStub::kMaximumSlots) { |
| 705 FastNewContextStub stub(heap_slots); | 704 FastNewContextStub stub(heap_slots); |
| 706 __ CallStub(&stub); | 705 __ CallStub(&stub); |
| 707 } else { | 706 } else { |
| 707 __ Push(x1); |
| 708 __ CallRuntime(Runtime::kNewFunctionContext, 1); | 708 __ CallRuntime(Runtime::kNewFunctionContext, 1); |
| 709 } | 709 } |
| 710 RecordSafepoint(Safepoint::kNoLazyDeopt); | 710 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 711 // Context is returned in both x0 and cp. It replaces the context passed to | 711 // Context is returned in x0. It replaces the context passed to us. It's |
| 712 // us. It's saved in the stack and kept live in cp. | 712 // saved in the stack and kept live in cp. |
| 713 __ Str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 713 __ Mov(cp, x0); |
| 714 __ Str(x0, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 714 // Copy any necessary parameters into the context. | 715 // Copy any necessary parameters into the context. |
| 715 int num_parameters = scope()->num_parameters(); | 716 int num_parameters = scope()->num_parameters(); |
| 716 for (int i = 0; i < num_parameters; i++) { | 717 for (int i = 0; i < num_parameters; i++) { |
| 717 Variable* var = scope()->parameter(i); | 718 Variable* var = scope()->parameter(i); |
| 718 if (var->IsContextSlot()) { | 719 if (var->IsContextSlot()) { |
| 719 Register value = x0; | 720 Register value = x0; |
| 720 Register scratch = x3; | 721 Register scratch = x3; |
| 721 | 722 |
| 722 int parameter_offset = StandardFrameConstants::kCallerSPOffset + | 723 int parameter_offset = StandardFrameConstants::kCallerSPOffset + |
| 723 (num_parameters - 1 - i) * kPointerSize; | 724 (num_parameters - 1 - i) * kPointerSize; |
| (...skipping 2542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3266 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 3267 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
| 3267 ASSERT(ToRegister(instr->global_object()).Is(x0)); | 3268 ASSERT(ToRegister(instr->global_object()).Is(x0)); |
| 3268 ASSERT(ToRegister(instr->result()).Is(x0)); | 3269 ASSERT(ToRegister(instr->result()).Is(x0)); |
| 3269 __ Mov(x2, Operand(instr->name())); | 3270 __ Mov(x2, Operand(instr->name())); |
| 3270 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; | 3271 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; |
| 3271 Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode); | 3272 Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode); |
| 3272 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3273 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3273 } | 3274 } |
| 3274 | 3275 |
| 3275 | 3276 |
| 3276 MemOperand LCodeGen::PrepareKeyedExternalArrayOperand(Register key, | 3277 MemOperand LCodeGen::PrepareKeyedExternalArrayOperand( |
| 3277 Register base, | 3278 Register key, |
| 3278 Register scratch, | 3279 Register base, |
| 3279 bool key_is_smi, | 3280 Register scratch, |
| 3280 bool key_is_constant, | 3281 bool key_is_smi, |
| 3281 int constant_key, | 3282 bool key_is_constant, |
| 3282 int element_size_shift, | 3283 int constant_key, |
| 3283 int additional_index) { | 3284 ElementsKind elements_kind, |
| 3285 int additional_index) { |
| 3286 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 3287 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) |
| 3288 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag |
| 3289 : 0; |
| 3290 |
| 3284 if (key_is_constant) { | 3291 if (key_is_constant) { |
| 3285 return MemOperand(base, (constant_key + additional_index) << | 3292 int base_offset = ((constant_key + additional_index) << element_size_shift); |
| 3286 element_size_shift); | 3293 return MemOperand(base, base_offset + additional_offset); |
| 3287 } | 3294 } |
| 3288 | 3295 |
| 3289 if (additional_index == 0) { | 3296 if (additional_index == 0) { |
| 3290 if (key_is_smi) { | 3297 if (key_is_smi) { |
| 3291 // Key is smi: untag, and scale by element size. | 3298 // Key is smi: untag, and scale by element size. |
| 3292 __ Add(scratch, base, Operand::UntagSmiAndScale(key, element_size_shift)); | 3299 __ Add(scratch, base, Operand::UntagSmiAndScale(key, element_size_shift)); |
| 3293 return MemOperand(scratch); | 3300 return MemOperand(scratch, additional_offset); |
| 3294 } else { | 3301 } else { |
| 3295 // Key is not smi, and element size is not byte: scale by element size. | 3302 // Key is not smi, and element size is not byte: scale by element size. |
| 3296 return MemOperand(base, key, LSL, element_size_shift); | 3303 if (additional_offset == 0) { |
| 3304 return MemOperand(base, key, LSL, element_size_shift); |
| 3305 } else { |
| 3306 __ Add(scratch, base, Operand(key, LSL, element_size_shift)); |
| 3307 return MemOperand(scratch, additional_offset); |
| 3308 } |
| 3297 } | 3309 } |
| 3298 } else { | 3310 } else { |
| 3299 if (key_is_smi) { | 3311 // TODO(all): Try to combine these cases a bit more intelligently. |
| 3300 __ SmiUntag(scratch, key); | 3312 if (additional_offset == 0) { |
| 3301 __ Add(scratch, scratch, additional_index); | 3313 if (key_is_smi) { |
| 3314 __ SmiUntag(scratch, key); |
| 3315 __ Add(scratch, scratch, additional_index); |
| 3316 } else { |
| 3317 __ Add(scratch, key, additional_index); |
| 3318 } |
| 3319 return MemOperand(base, scratch, LSL, element_size_shift); |
| 3302 } else { | 3320 } else { |
| 3303 __ Add(scratch, key, additional_index); | 3321 if (key_is_smi) { |
| 3322 __ Add(scratch, base, |
| 3323 Operand::UntagSmiAndScale(key, element_size_shift)); |
| 3324 } else { |
| 3325 __ Add(scratch, base, Operand(key, LSL, element_size_shift)); |
| 3326 } |
| 3327 return MemOperand( |
| 3328 scratch, |
| 3329 (additional_index << element_size_shift) + additional_offset); |
| 3304 } | 3330 } |
| 3305 return MemOperand(base, scratch, LSL, element_size_shift); | |
| 3306 } | 3331 } |
| 3307 } | 3332 } |
| 3308 | 3333 |
| 3309 | 3334 |
| 3310 void LCodeGen::DoLoadKeyedExternal(LLoadKeyedExternal* instr) { | 3335 void LCodeGen::DoLoadKeyedExternal(LLoadKeyedExternal* instr) { |
| 3311 Register ext_ptr = ToRegister(instr->elements()); | 3336 Register ext_ptr = ToRegister(instr->elements()); |
| 3312 Register scratch; | 3337 Register scratch; |
| 3313 ElementsKind elements_kind = instr->elements_kind(); | 3338 ElementsKind elements_kind = instr->elements_kind(); |
| 3314 | 3339 |
| 3315 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); | 3340 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); |
| 3316 bool key_is_constant = instr->key()->IsConstantOperand(); | 3341 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 3317 Register key = no_reg; | 3342 Register key = no_reg; |
| 3318 int constant_key = 0; | 3343 int constant_key = 0; |
| 3319 if (key_is_constant) { | 3344 if (key_is_constant) { |
| 3320 ASSERT(instr->temp() == NULL); | 3345 ASSERT(instr->temp() == NULL); |
| 3321 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3346 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 3322 if (constant_key & 0xf0000000) { | 3347 if (constant_key & 0xf0000000) { |
| 3323 Abort(kArrayIndexConstantValueTooBig); | 3348 Abort(kArrayIndexConstantValueTooBig); |
| 3324 } | 3349 } |
| 3325 } else { | 3350 } else { |
| 3326 scratch = ToRegister(instr->temp()); | 3351 scratch = ToRegister(instr->temp()); |
| 3327 key = ToRegister(instr->key()); | 3352 key = ToRegister(instr->key()); |
| 3328 } | 3353 } |
| 3329 | 3354 |
| 3330 int element_size_shift = ElementsKindToShiftSize(elements_kind); | |
| 3331 MemOperand mem_op = | 3355 MemOperand mem_op = |
| 3332 PrepareKeyedExternalArrayOperand(key, ext_ptr, scratch, key_is_smi, | 3356 PrepareKeyedExternalArrayOperand(key, ext_ptr, scratch, key_is_smi, |
| 3333 key_is_constant, constant_key, | 3357 key_is_constant, constant_key, |
| 3334 element_size_shift, | 3358 elements_kind, |
| 3335 instr->additional_index()); | 3359 instr->additional_index()); |
| 3336 | 3360 |
| 3337 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3361 if ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || |
| 3362 (elements_kind == FLOAT32_ELEMENTS)) { |
| 3338 DoubleRegister result = ToDoubleRegister(instr->result()); | 3363 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3339 __ Ldr(result.S(), mem_op); | 3364 __ Ldr(result.S(), mem_op); |
| 3340 __ Fcvt(result, result.S()); | 3365 __ Fcvt(result, result.S()); |
| 3341 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3366 } else if ((elements_kind == EXTERNAL_DOUBLE_ELEMENTS) || |
| 3367 (elements_kind == FLOAT64_ELEMENTS)) { |
| 3342 DoubleRegister result = ToDoubleRegister(instr->result()); | 3368 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3343 __ Ldr(result, mem_op); | 3369 __ Ldr(result, mem_op); |
| 3344 } else { | 3370 } else { |
| 3345 Register result = ToRegister(instr->result()); | 3371 Register result = ToRegister(instr->result()); |
| 3346 | 3372 |
| 3347 switch (elements_kind) { | 3373 switch (elements_kind) { |
| 3348 case EXTERNAL_BYTE_ELEMENTS: __ Ldrsb(result, mem_op); break; | 3374 case EXTERNAL_BYTE_ELEMENTS: |
| 3349 case EXTERNAL_PIXEL_ELEMENTS: // Fall through. | 3375 case INT8_ELEMENTS: |
| 3350 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ Ldrb(result, mem_op); break; | 3376 __ Ldrsb(result, mem_op); |
| 3351 case EXTERNAL_SHORT_ELEMENTS: __ Ldrsh(result, mem_op); break; | 3377 break; |
| 3352 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ Ldrh(result, mem_op); break; | 3378 case EXTERNAL_PIXEL_ELEMENTS: |
| 3353 case EXTERNAL_INT_ELEMENTS: __ Ldrsw(result, mem_op); break; | 3379 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 3380 case UINT8_ELEMENTS: |
| 3381 case UINT8_CLAMPED_ELEMENTS: |
| 3382 __ Ldrb(result, mem_op); |
| 3383 break; |
| 3384 case EXTERNAL_SHORT_ELEMENTS: |
| 3385 case INT16_ELEMENTS: |
| 3386 __ Ldrsh(result, mem_op); |
| 3387 break; |
| 3388 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 3389 case UINT16_ELEMENTS: |
| 3390 __ Ldrh(result, mem_op); |
| 3391 break; |
| 3392 case EXTERNAL_INT_ELEMENTS: |
| 3393 case INT32_ELEMENTS: |
| 3394 __ Ldrsw(result, mem_op); |
| 3395 break; |
| 3354 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3396 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 3397 case UINT32_ELEMENTS: |
| 3355 __ Ldr(result.W(), mem_op); | 3398 __ Ldr(result.W(), mem_op); |
| 3356 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { | 3399 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { |
| 3357 // Deopt if value > 0x80000000. | 3400 // Deopt if value > 0x80000000. |
| 3358 __ Tst(result, 0xFFFFFFFF80000000); | 3401 __ Tst(result, 0xFFFFFFFF80000000); |
| 3359 DeoptimizeIf(ne, instr->environment()); | 3402 DeoptimizeIf(ne, instr->environment()); |
| 3360 } | 3403 } |
| 3361 break; | 3404 break; |
| 3405 case FLOAT32_ELEMENTS: |
| 3406 case FLOAT64_ELEMENTS: |
| 3362 case EXTERNAL_FLOAT_ELEMENTS: | 3407 case EXTERNAL_FLOAT_ELEMENTS: |
| 3363 case EXTERNAL_DOUBLE_ELEMENTS: | 3408 case EXTERNAL_DOUBLE_ELEMENTS: |
| 3364 case FAST_HOLEY_DOUBLE_ELEMENTS: | 3409 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 3365 case FAST_HOLEY_ELEMENTS: | 3410 case FAST_HOLEY_ELEMENTS: |
| 3366 case FAST_HOLEY_SMI_ELEMENTS: | 3411 case FAST_HOLEY_SMI_ELEMENTS: |
| 3367 case FAST_DOUBLE_ELEMENTS: | 3412 case FAST_DOUBLE_ELEMENTS: |
| 3368 case FAST_ELEMENTS: | 3413 case FAST_ELEMENTS: |
| 3369 case FAST_SMI_ELEMENTS: | 3414 case FAST_SMI_ELEMENTS: |
| 3370 case DICTIONARY_ELEMENTS: | 3415 case DICTIONARY_ELEMENTS: |
| 3371 case NON_STRICT_ARGUMENTS_ELEMENTS: | 3416 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| (...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4765 DeoptimizeIfRoot( | 4810 DeoptimizeIfRoot( |
| 4766 payload, Heap::kTheHoleValueRootIndex, instr->environment()); | 4811 payload, Heap::kTheHoleValueRootIndex, instr->environment()); |
| 4767 } | 4812 } |
| 4768 | 4813 |
| 4769 // Store the value. | 4814 // Store the value. |
| 4770 __ Str(value, FieldMemOperand(cell, Cell::kValueOffset)); | 4815 __ Str(value, FieldMemOperand(cell, Cell::kValueOffset)); |
| 4771 // Cells are always rescanned, so no write barrier here. | 4816 // Cells are always rescanned, so no write barrier here. |
| 4772 } | 4817 } |
| 4773 | 4818 |
| 4774 | 4819 |
| 4775 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { | |
| 4776 ASSERT(ToRegister(instr->global_object()).Is(x1)); | |
| 4777 ASSERT(ToRegister(instr->value()).Is(x0)); | |
| 4778 | |
| 4779 __ Mov(x2, Operand(instr->name())); | |
| 4780 Handle<Code> ic = StoreIC::initialize_stub(isolate(), | |
| 4781 instr->strict_mode_flag(), | |
| 4782 CONTEXTUAL); | |
| 4783 CallCode(ic, RelocInfo::CODE_TARGET, instr); | |
| 4784 } | |
| 4785 | |
| 4786 | |
| 4787 void LCodeGen::DoStoreKeyedExternal(LStoreKeyedExternal* instr) { | 4820 void LCodeGen::DoStoreKeyedExternal(LStoreKeyedExternal* instr) { |
| 4788 Register ext_ptr = ToRegister(instr->elements()); | 4821 Register ext_ptr = ToRegister(instr->elements()); |
| 4789 Register key = no_reg; | 4822 Register key = no_reg; |
| 4790 Register scratch; | 4823 Register scratch; |
| 4791 ElementsKind elements_kind = instr->elements_kind(); | 4824 ElementsKind elements_kind = instr->elements_kind(); |
| 4792 | 4825 |
| 4793 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); | 4826 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); |
| 4794 bool key_is_constant = instr->key()->IsConstantOperand(); | 4827 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 4795 int constant_key = 0; | 4828 int constant_key = 0; |
| 4796 if (key_is_constant) { | 4829 if (key_is_constant) { |
| 4797 ASSERT(instr->temp() == NULL); | 4830 ASSERT(instr->temp() == NULL); |
| 4798 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4831 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 4799 if (constant_key & 0xf0000000) { | 4832 if (constant_key & 0xf0000000) { |
| 4800 Abort(kArrayIndexConstantValueTooBig); | 4833 Abort(kArrayIndexConstantValueTooBig); |
| 4801 } | 4834 } |
| 4802 } else { | 4835 } else { |
| 4803 key = ToRegister(instr->key()); | 4836 key = ToRegister(instr->key()); |
| 4804 scratch = ToRegister(instr->temp()); | 4837 scratch = ToRegister(instr->temp()); |
| 4805 } | 4838 } |
| 4806 | 4839 |
| 4807 int element_size_shift = ElementsKindToShiftSize(elements_kind); | |
| 4808 MemOperand dst = | 4840 MemOperand dst = |
| 4809 PrepareKeyedExternalArrayOperand(key, ext_ptr, scratch, key_is_smi, | 4841 PrepareKeyedExternalArrayOperand(key, ext_ptr, scratch, key_is_smi, |
| 4810 key_is_constant, constant_key, | 4842 key_is_constant, constant_key, |
| 4811 element_size_shift, | 4843 elements_kind, |
| 4812 instr->additional_index()); | 4844 instr->additional_index()); |
| 4813 | 4845 |
| 4814 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4846 if ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || |
| 4847 (elements_kind == FLOAT32_ELEMENTS)) { |
| 4815 DoubleRegister value = ToDoubleRegister(instr->value()); | 4848 DoubleRegister value = ToDoubleRegister(instr->value()); |
| 4816 DoubleRegister dbl_scratch = double_scratch(); | 4849 DoubleRegister dbl_scratch = double_scratch(); |
| 4817 __ Fcvt(dbl_scratch.S(), value); | 4850 __ Fcvt(dbl_scratch.S(), value); |
| 4818 __ Str(dbl_scratch.S(), dst); | 4851 __ Str(dbl_scratch.S(), dst); |
| 4819 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4852 } else if ((elements_kind == EXTERNAL_DOUBLE_ELEMENTS) || |
| 4853 (elements_kind == FLOAT64_ELEMENTS)) { |
| 4820 DoubleRegister value = ToDoubleRegister(instr->value()); | 4854 DoubleRegister value = ToDoubleRegister(instr->value()); |
| 4821 __ Str(value, dst); | 4855 __ Str(value, dst); |
| 4822 } else { | 4856 } else { |
| 4823 Register value = ToRegister(instr->value()); | 4857 Register value = ToRegister(instr->value()); |
| 4824 | 4858 |
| 4825 switch (elements_kind) { | 4859 switch (elements_kind) { |
| 4826 case EXTERNAL_PIXEL_ELEMENTS: | 4860 case EXTERNAL_PIXEL_ELEMENTS: |
| 4827 case EXTERNAL_BYTE_ELEMENTS: | 4861 case EXTERNAL_BYTE_ELEMENTS: |
| 4828 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: __ Strb(value, dst); break; | 4862 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 4863 case UINT8_ELEMENTS: |
| 4864 case UINT8_CLAMPED_ELEMENTS: |
| 4865 case INT8_ELEMENTS: |
| 4866 __ Strb(value, dst); |
| 4867 break; |
| 4829 case EXTERNAL_SHORT_ELEMENTS: | 4868 case EXTERNAL_SHORT_ELEMENTS: |
| 4830 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: __ Strh(value, dst); break; | 4869 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 4870 case INT16_ELEMENTS: |
| 4871 case UINT16_ELEMENTS: |
| 4872 __ Strh(value, dst); |
| 4873 break; |
| 4831 case EXTERNAL_INT_ELEMENTS: | 4874 case EXTERNAL_INT_ELEMENTS: |
| 4832 case EXTERNAL_UNSIGNED_INT_ELEMENTS: __ Str(value.W(), dst); break; | 4875 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 4876 case INT32_ELEMENTS: |
| 4877 case UINT32_ELEMENTS: |
| 4878 __ Str(value.W(), dst); |
| 4879 break; |
| 4880 case FLOAT32_ELEMENTS: |
| 4881 case FLOAT64_ELEMENTS: |
| 4833 case EXTERNAL_FLOAT_ELEMENTS: | 4882 case EXTERNAL_FLOAT_ELEMENTS: |
| 4834 case EXTERNAL_DOUBLE_ELEMENTS: | 4883 case EXTERNAL_DOUBLE_ELEMENTS: |
| 4835 case FAST_DOUBLE_ELEMENTS: | 4884 case FAST_DOUBLE_ELEMENTS: |
| 4836 case FAST_ELEMENTS: | 4885 case FAST_ELEMENTS: |
| 4837 case FAST_SMI_ELEMENTS: | 4886 case FAST_SMI_ELEMENTS: |
| 4838 case FAST_HOLEY_DOUBLE_ELEMENTS: | 4887 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 4839 case FAST_HOLEY_ELEMENTS: | 4888 case FAST_HOLEY_ELEMENTS: |
| 4840 case FAST_HOLEY_SMI_ELEMENTS: | 4889 case FAST_HOLEY_SMI_ELEMENTS: |
| 4841 case DICTIONARY_ELEMENTS: | 4890 case DICTIONARY_ELEMENTS: |
| 4842 case NON_STRICT_ARGUMENTS_ELEMENTS: | 4891 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5022 } | 5071 } |
| 5023 | 5072 |
| 5024 | 5073 |
| 5025 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 5074 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
| 5026 ASSERT(ToRegister(instr->value()).is(x0)); | 5075 ASSERT(ToRegister(instr->value()).is(x0)); |
| 5027 ASSERT(ToRegister(instr->object()).is(x1)); | 5076 ASSERT(ToRegister(instr->object()).is(x1)); |
| 5028 | 5077 |
| 5029 // Name must be in x2. | 5078 // Name must be in x2. |
| 5030 __ Mov(x2, Operand(instr->name())); | 5079 __ Mov(x2, Operand(instr->name())); |
| 5031 Handle<Code> ic = StoreIC::initialize_stub(isolate(), | 5080 Handle<Code> ic = StoreIC::initialize_stub(isolate(), |
| 5032 instr->strict_mode_flag(), | 5081 instr->strict_mode_flag()); |
| 5033 NOT_CONTEXTUAL); | |
| 5034 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 5082 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 5035 } | 5083 } |
| 5036 | 5084 |
| 5037 | 5085 |
| 5038 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 5086 void LCodeGen::DoStringAdd(LStringAdd* instr) { |
| 5039 Register left = ToRegister(instr->left()); | 5087 ASSERT(ToRegister(instr->left()).Is(x1)); |
| 5040 Register right = ToRegister(instr->right()); | 5088 ASSERT(ToRegister(instr->right()).Is(x0)); |
| 5041 if (FLAG_new_string_add) { | 5089 StringAddStub stub(instr->hydrogen()->flags(), |
| 5042 ASSERT(left.Is(x1)); | 5090 isolate()->heap()->GetPretenureMode()); |
| 5043 ASSERT(right.Is(x0)); | 5091 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 5044 NewStringAddStub stub(instr->hydrogen()->flags(), | |
| 5045 isolate()->heap()->GetPretenureMode()); | |
| 5046 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 5047 } else { | |
| 5048 __ Push(left, right); | |
| 5049 StringAddStub stub(instr->hydrogen()->flags()); | |
| 5050 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 5051 } | |
| 5052 } | 5092 } |
| 5053 | 5093 |
| 5054 | 5094 |
| 5055 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 5095 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
| 5056 class DeferredStringCharCodeAt: public LDeferredCode { | 5096 class DeferredStringCharCodeAt: public LDeferredCode { |
| 5057 public: | 5097 public: |
| 5058 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 5098 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
| 5059 : LDeferredCode(codegen), instr_(instr) { } | 5099 : LDeferredCode(codegen), instr_(instr) { } |
| 5060 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } | 5100 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } |
| 5061 virtual LInstruction* instr() { return instr_; } | 5101 virtual LInstruction* instr() { return instr_; } |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5631 __ Bind(&out_of_object); | 5671 __ Bind(&out_of_object); |
| 5632 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5672 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 5633 // Index is equal to negated out of object property index plus 1. | 5673 // Index is equal to negated out of object property index plus 1. |
| 5634 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5674 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 5635 __ Ldr(result, FieldMemOperand(result, | 5675 __ Ldr(result, FieldMemOperand(result, |
| 5636 FixedArray::kHeaderSize - kPointerSize)); | 5676 FixedArray::kHeaderSize - kPointerSize)); |
| 5637 __ Bind(&done); | 5677 __ Bind(&done); |
| 5638 } | 5678 } |
| 5639 | 5679 |
| 5640 } } // namespace v8::internal | 5680 } } // namespace v8::internal |
| OLD | NEW |