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 3353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3364 case FAST_DOUBLE_ELEMENTS: | 3364 case FAST_DOUBLE_ELEMENTS: |
3365 case DICTIONARY_ELEMENTS: | 3365 case DICTIONARY_ELEMENTS: |
3366 case NON_STRICT_ARGUMENTS_ELEMENTS: | 3366 case NON_STRICT_ARGUMENTS_ELEMENTS: |
3367 UNREACHABLE(); | 3367 UNREACHABLE(); |
3368 return false; | 3368 return false; |
3369 } | 3369 } |
3370 return false; | 3370 return false; |
3371 } | 3371 } |
3372 | 3372 |
3373 | 3373 |
| 3374 static void GenerateSmiKeyCheck(MacroAssembler* masm, |
| 3375 Register key, |
| 3376 Register scratch0, |
| 3377 Register scratch1, |
| 3378 FPURegister double_scratch0, |
| 3379 Label* fail) { |
| 3380 if (CpuFeatures::IsSupported(FPU)) { |
| 3381 CpuFeatures::Scope scope(FPU); |
| 3382 Label key_ok; |
| 3383 // Check for smi or a smi inside a heap number. We convert the heap |
| 3384 // number and check if the conversion is exact and fits into the smi |
| 3385 // range. |
| 3386 __ JumpIfSmi(key, &key_ok); |
| 3387 __ CheckMap(key, |
| 3388 scratch0, |
| 3389 Heap::kHeapNumberMapRootIndex, |
| 3390 fail, |
| 3391 DONT_DO_SMI_CHECK); |
| 3392 __ ldc1(double_scratch0, FieldMemOperand(key, HeapNumber::kValueOffset)); |
| 3393 __ EmitFPUTruncate(kRoundToZero, |
| 3394 double_scratch0, |
| 3395 double_scratch0, |
| 3396 scratch0, |
| 3397 scratch1, |
| 3398 kCheckForInexactConversion); |
| 3399 |
| 3400 __ Branch(fail, ne, scratch1, Operand(zero_reg)); |
| 3401 |
| 3402 __ mfc1(scratch0, double_scratch0); |
| 3403 __ SmiTagCheckOverflow(key, scratch0, scratch1); |
| 3404 __ BranchOnOverflow(fail, scratch1); |
| 3405 __ bind(&key_ok); |
| 3406 } else { |
| 3407 // Check that the key is a smi. |
| 3408 __ JumpIfNotSmi(key, fail); |
| 3409 } |
| 3410 } |
| 3411 |
| 3412 |
3374 void KeyedLoadStubCompiler::GenerateLoadExternalArray( | 3413 void KeyedLoadStubCompiler::GenerateLoadExternalArray( |
3375 MacroAssembler* masm, | 3414 MacroAssembler* masm, |
3376 ElementsKind elements_kind) { | 3415 ElementsKind elements_kind) { |
3377 // ---------- S t a t e -------------- | 3416 // ---------- S t a t e -------------- |
3378 // -- ra : return address | 3417 // -- ra : return address |
3379 // -- a0 : key | 3418 // -- a0 : key |
3380 // -- a1 : receiver | 3419 // -- a1 : receiver |
3381 // ----------------------------------- | 3420 // ----------------------------------- |
3382 Label miss_force_generic, slow, failed_allocation; | 3421 Label miss_force_generic, slow, failed_allocation; |
3383 | 3422 |
3384 Register key = a0; | 3423 Register key = a0; |
3385 Register receiver = a1; | 3424 Register receiver = a1; |
3386 | 3425 |
3387 // This stub is meant to be tail-jumped to, the receiver must already | 3426 // This stub is meant to be tail-jumped to, the receiver must already |
3388 // have been verified by the caller to not be a smi. | 3427 // have been verified by the caller to not be a smi. |
3389 | 3428 |
3390 // Check that the key is a smi. | 3429 // Check that the key is a smi or a heap number convertible to a smi. |
3391 __ JumpIfNotSmi(key, &miss_force_generic); | 3430 GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic); |
3392 | 3431 |
3393 __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 3432 __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
3394 // a3: elements array | 3433 // a3: elements array |
3395 | 3434 |
3396 // Check that the index is in range. | 3435 // Check that the index is in range. |
3397 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); | 3436 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); |
3398 __ sra(t2, key, kSmiTagSize); | 3437 __ sra(t2, key, kSmiTagSize); |
3399 // Unsigned comparison catches both negative and too-large values. | 3438 // Unsigned comparison catches both negative and too-large values. |
3400 __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1)); | 3439 __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1)); |
3401 | 3440 |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3719 | 3758 |
3720 // Register usage. | 3759 // Register usage. |
3721 Register value = a0; | 3760 Register value = a0; |
3722 Register key = a1; | 3761 Register key = a1; |
3723 Register receiver = a2; | 3762 Register receiver = a2; |
3724 // a3 mostly holds the elements array or the destination external array. | 3763 // a3 mostly holds the elements array or the destination external array. |
3725 | 3764 |
3726 // This stub is meant to be tail-jumped to, the receiver must already | 3765 // This stub is meant to be tail-jumped to, the receiver must already |
3727 // have been verified by the caller to not be a smi. | 3766 // have been verified by the caller to not be a smi. |
3728 | 3767 |
3729 // Check that the key is a smi. | 3768 // Check that the key is a smi or a heap number convertible to a smi. |
3730 __ JumpIfNotSmi(key, &miss_force_generic); | 3769 GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic); |
3731 | 3770 |
3732 __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 3771 __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
3733 | 3772 |
3734 // Check that the index is in range. | 3773 // Check that the index is in range. |
3735 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); | 3774 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); |
3736 // Unsigned comparison catches both negative and too-large values. | 3775 // Unsigned comparison catches both negative and too-large values. |
3737 __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1)); | 3776 __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1)); |
3738 | 3777 |
3739 // Handle both smis and HeapNumbers in the fast path. Go to the | 3778 // Handle both smis and HeapNumbers in the fast path. Go to the |
3740 // runtime for all other kinds of values. | 3779 // runtime for all other kinds of values. |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4099 // ----------- S t a t e ------------- | 4138 // ----------- S t a t e ------------- |
4100 // -- ra : return address | 4139 // -- ra : return address |
4101 // -- a0 : key | 4140 // -- a0 : key |
4102 // -- a1 : receiver | 4141 // -- a1 : receiver |
4103 // ----------------------------------- | 4142 // ----------------------------------- |
4104 Label miss_force_generic; | 4143 Label miss_force_generic; |
4105 | 4144 |
4106 // This stub is meant to be tail-jumped to, the receiver must already | 4145 // This stub is meant to be tail-jumped to, the receiver must already |
4107 // have been verified by the caller to not be a smi. | 4146 // have been verified by the caller to not be a smi. |
4108 | 4147 |
4109 // Check that the key is a smi. | 4148 // Check that the key is a smi or a heap number convertible to a smi. |
4110 __ JumpIfNotSmi(a0, &miss_force_generic, at, USE_DELAY_SLOT); | 4149 GenerateSmiKeyCheck(masm, a0, t0, t1, f2, &miss_force_generic); |
4111 // The delay slot can be safely used here, a1 is an object pointer. | |
4112 | 4150 |
4113 // Get the elements array. | 4151 // Get the elements array. |
4114 __ lw(a2, FieldMemOperand(a1, JSObject::kElementsOffset)); | 4152 __ lw(a2, FieldMemOperand(a1, JSObject::kElementsOffset)); |
4115 __ AssertFastElements(a2); | 4153 __ AssertFastElements(a2); |
4116 | 4154 |
4117 // Check that the key is within bounds. | 4155 // Check that the key is within bounds. |
4118 __ lw(a3, FieldMemOperand(a2, FixedArray::kLengthOffset)); | 4156 __ lw(a3, FieldMemOperand(a2, FixedArray::kLengthOffset)); |
4119 __ Branch(USE_DELAY_SLOT, &miss_force_generic, hs, a0, Operand(a3)); | 4157 __ Branch(USE_DELAY_SLOT, &miss_force_generic, hs, a0, Operand(a3)); |
4120 | 4158 |
4121 // Load the result and make sure it's not the hole. | 4159 // Load the result and make sure it's not the hole. |
(...skipping 29 matching lines...) Expand all Loading... |
4151 Register heap_number_reg = a2; | 4189 Register heap_number_reg = a2; |
4152 Register indexed_double_offset = a3; | 4190 Register indexed_double_offset = a3; |
4153 Register scratch = t0; | 4191 Register scratch = t0; |
4154 Register scratch2 = t1; | 4192 Register scratch2 = t1; |
4155 Register scratch3 = t2; | 4193 Register scratch3 = t2; |
4156 Register heap_number_map = t3; | 4194 Register heap_number_map = t3; |
4157 | 4195 |
4158 // This stub is meant to be tail-jumped to, the receiver must already | 4196 // This stub is meant to be tail-jumped to, the receiver must already |
4159 // have been verified by the caller to not be a smi. | 4197 // have been verified by the caller to not be a smi. |
4160 | 4198 |
4161 // Check that the key is a smi. | 4199 // Check that the key is a smi or a heap number convertible to a smi. |
4162 __ JumpIfNotSmi(key_reg, &miss_force_generic); | 4200 GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic); |
4163 | 4201 |
4164 // Get the elements array. | 4202 // Get the elements array. |
4165 __ lw(elements_reg, | 4203 __ lw(elements_reg, |
4166 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); | 4204 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
4167 | 4205 |
4168 // Check that the key is within bounds. | 4206 // Check that the key is within bounds. |
4169 __ lw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); | 4207 __ lw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
4170 __ Branch(&miss_force_generic, hs, key_reg, Operand(scratch)); | 4208 __ Branch(&miss_force_generic, hs, key_reg, Operand(scratch)); |
4171 | 4209 |
4172 // Load the upper word of the double in the fixed array and test for NaN. | 4210 // Load the upper word of the double in the fixed array and test for NaN. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4226 Register receiver_reg = a2; | 4264 Register receiver_reg = a2; |
4227 Register scratch = t0; | 4265 Register scratch = t0; |
4228 Register elements_reg = a3; | 4266 Register elements_reg = a3; |
4229 Register length_reg = t1; | 4267 Register length_reg = t1; |
4230 Register scratch2 = t2; | 4268 Register scratch2 = t2; |
4231 Register scratch3 = t3; | 4269 Register scratch3 = t3; |
4232 | 4270 |
4233 // This stub is meant to be tail-jumped to, the receiver must already | 4271 // This stub is meant to be tail-jumped to, the receiver must already |
4234 // have been verified by the caller to not be a smi. | 4272 // have been verified by the caller to not be a smi. |
4235 | 4273 |
4236 // Check that the key is a smi. | 4274 // Check that the key is a smi or a heap number convertible to a smi. |
4237 __ JumpIfNotSmi(key_reg, &miss_force_generic); | 4275 GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic); |
4238 | 4276 |
4239 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { | 4277 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
4240 __ JumpIfNotSmi(value_reg, &transition_elements_kind); | 4278 __ JumpIfNotSmi(value_reg, &transition_elements_kind); |
4241 } | 4279 } |
4242 | 4280 |
4243 // Check that the key is within bounds. | 4281 // Check that the key is within bounds. |
4244 __ lw(elements_reg, | 4282 __ lw(elements_reg, |
4245 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); | 4283 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
4246 if (is_js_array) { | 4284 if (is_js_array) { |
4247 __ lw(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); | 4285 __ lw(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4393 Register receiver_reg = a2; | 4431 Register receiver_reg = a2; |
4394 Register elements_reg = a3; | 4432 Register elements_reg = a3; |
4395 Register scratch1 = t0; | 4433 Register scratch1 = t0; |
4396 Register scratch2 = t1; | 4434 Register scratch2 = t1; |
4397 Register scratch3 = t2; | 4435 Register scratch3 = t2; |
4398 Register scratch4 = t3; | 4436 Register scratch4 = t3; |
4399 Register length_reg = t3; | 4437 Register length_reg = t3; |
4400 | 4438 |
4401 // This stub is meant to be tail-jumped to, the receiver must already | 4439 // This stub is meant to be tail-jumped to, the receiver must already |
4402 // have been verified by the caller to not be a smi. | 4440 // have been verified by the caller to not be a smi. |
4403 __ JumpIfNotSmi(key_reg, &miss_force_generic); | 4441 |
| 4442 // Check that the key is a smi or a heap number convertible to a smi. |
| 4443 GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic); |
4404 | 4444 |
4405 __ lw(elements_reg, | 4445 __ lw(elements_reg, |
4406 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); | 4446 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
4407 | 4447 |
4408 // Check that the key is within bounds. | 4448 // Check that the key is within bounds. |
4409 if (is_js_array) { | 4449 if (is_js_array) { |
4410 __ lw(scratch1, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); | 4450 __ lw(scratch1, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
4411 } else { | 4451 } else { |
4412 __ lw(scratch1, | 4452 __ lw(scratch1, |
4413 FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); | 4453 FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4510 __ Jump(ic_slow, RelocInfo::CODE_TARGET); | 4550 __ Jump(ic_slow, RelocInfo::CODE_TARGET); |
4511 } | 4551 } |
4512 } | 4552 } |
4513 | 4553 |
4514 | 4554 |
4515 #undef __ | 4555 #undef __ |
4516 | 4556 |
4517 } } // namespace v8::internal | 4557 } } // namespace v8::internal |
4518 | 4558 |
4519 #endif // V8_TARGET_ARCH_MIPS | 4559 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |