| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 8370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8381 if (loop_nesting() > 0 && key_type->IsLikelySmi()) { | 8381 if (loop_nesting() > 0 && key_type->IsLikelySmi()) { |
| 8382 Comment cmnt(masm(), "[ Inlined store to keyed Property"); | 8382 Comment cmnt(masm(), "[ Inlined store to keyed Property"); |
| 8383 | 8383 |
| 8384 // Get the receiver, key and value into registers. | 8384 // Get the receiver, key and value into registers. |
| 8385 result = frame()->Pop(); | 8385 result = frame()->Pop(); |
| 8386 Result key = frame()->Pop(); | 8386 Result key = frame()->Pop(); |
| 8387 Result receiver = frame()->Pop(); | 8387 Result receiver = frame()->Pop(); |
| 8388 | 8388 |
| 8389 Result tmp = allocator_->Allocate(); | 8389 Result tmp = allocator_->Allocate(); |
| 8390 ASSERT(tmp.is_valid()); | 8390 ASSERT(tmp.is_valid()); |
| 8391 Result tmp2 = allocator_->Allocate(); |
| 8392 ASSERT(tmp2.is_valid()); |
| 8391 | 8393 |
| 8392 // Determine whether the value is a constant before putting it in a | 8394 // Determine whether the value is a constant before putting it in a |
| 8393 // register. | 8395 // register. |
| 8394 bool value_is_constant = result.is_constant(); | 8396 bool value_is_constant = result.is_constant(); |
| 8395 | 8397 |
| 8396 // Make sure that value, key and receiver are in registers. | 8398 // Make sure that value, key and receiver are in registers. |
| 8397 result.ToRegister(); | 8399 result.ToRegister(); |
| 8398 key.ToRegister(); | 8400 key.ToRegister(); |
| 8399 receiver.ToRegister(); | 8401 receiver.ToRegister(); |
| 8400 | 8402 |
| 8401 DeferredReferenceSetKeyedValue* deferred = | 8403 DeferredReferenceSetKeyedValue* deferred = |
| 8402 new DeferredReferenceSetKeyedValue(result.reg(), | 8404 new DeferredReferenceSetKeyedValue(result.reg(), |
| 8403 key.reg(), | 8405 key.reg(), |
| 8404 receiver.reg(), | 8406 receiver.reg(), |
| 8405 tmp.reg()); | 8407 tmp.reg()); |
| 8406 | 8408 |
| 8407 // Check that the value is a smi if it is not a constant. We can skip | 8409 // Check that the receiver is not a smi. |
| 8408 // the write barrier for smis and constants. | 8410 __ test(receiver.reg(), Immediate(kSmiTagMask)); |
| 8409 if (!value_is_constant) { | 8411 deferred->Branch(zero); |
| 8410 __ test(result.reg(), Immediate(kSmiTagMask)); | |
| 8411 deferred->Branch(not_zero); | |
| 8412 } | |
| 8413 | 8412 |
| 8414 // Check that the key is a smi. | 8413 // Check that the key is a smi. |
| 8415 if (!key.is_smi()) { | 8414 if (!key.is_smi()) { |
| 8416 __ test(key.reg(), Immediate(kSmiTagMask)); | 8415 __ test(key.reg(), Immediate(kSmiTagMask)); |
| 8417 deferred->Branch(not_zero); | 8416 deferred->Branch(not_zero); |
| 8418 } else { | 8417 } else { |
| 8419 if (FLAG_debug_code) __ AbortIfNotSmi(key.reg()); | 8418 if (FLAG_debug_code) __ AbortIfNotSmi(key.reg()); |
| 8420 } | 8419 } |
| 8421 | 8420 |
| 8422 // Check that the receiver is not a smi. | |
| 8423 __ test(receiver.reg(), Immediate(kSmiTagMask)); | |
| 8424 deferred->Branch(zero); | |
| 8425 | |
| 8426 // Check that the receiver is a JSArray. | 8421 // Check that the receiver is a JSArray. |
| 8427 __ CmpObjectType(receiver.reg(), JS_ARRAY_TYPE, tmp.reg()); | 8422 __ CmpObjectType(receiver.reg(), JS_ARRAY_TYPE, tmp.reg()); |
| 8428 deferred->Branch(not_equal); | 8423 deferred->Branch(not_equal); |
| 8429 | 8424 |
| 8430 // Check that the key is within bounds. Both the key and the length of | 8425 // Check that the key is within bounds. Both the key and the length of |
| 8431 // the JSArray are smis. Use unsigned comparison to handle negative keys. | 8426 // the JSArray are smis. Use unsigned comparison to handle negative keys. |
| 8432 __ cmp(key.reg(), | 8427 __ cmp(key.reg(), |
| 8433 FieldOperand(receiver.reg(), JSArray::kLengthOffset)); | 8428 FieldOperand(receiver.reg(), JSArray::kLengthOffset)); |
| 8434 deferred->Branch(above_equal); | 8429 deferred->Branch(above_equal); |
| 8435 | 8430 |
| 8436 // Get the elements array from the receiver and check that it is not a | 8431 // Get the elements array from the receiver and check that it is not a |
| 8437 // dictionary. | 8432 // dictionary. |
| 8438 __ mov(tmp.reg(), | 8433 __ mov(tmp.reg(), |
| 8439 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); | 8434 FieldOperand(receiver.reg(), JSArray::kElementsOffset)); |
| 8435 |
| 8436 // Check whether it is possible to omit the write barrier. If the elements |
| 8437 // array is in new space or the value written is a smi we can safely update |
| 8438 // the elements array without updating the remembered set. |
| 8439 Label in_new_space; |
| 8440 __ InNewSpace(tmp.reg(), tmp2.reg(), equal, &in_new_space); |
| 8441 if (!value_is_constant) { |
| 8442 __ test(result.reg(), Immediate(kSmiTagMask)); |
| 8443 deferred->Branch(not_zero); |
| 8444 } |
| 8445 |
| 8446 __ bind(&in_new_space); |
| 8440 // Bind the deferred code patch site to be able to locate the fixed | 8447 // Bind the deferred code patch site to be able to locate the fixed |
| 8441 // array map comparison. When debugging, we patch this comparison to | 8448 // array map comparison. When debugging, we patch this comparison to |
| 8442 // always fail so that we will hit the IC call in the deferred code | 8449 // always fail so that we will hit the IC call in the deferred code |
| 8443 // which will allow the debugger to break for fast case stores. | 8450 // which will allow the debugger to break for fast case stores. |
| 8444 __ bind(deferred->patch_site()); | 8451 __ bind(deferred->patch_site()); |
| 8445 __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset), | 8452 __ cmp(FieldOperand(tmp.reg(), HeapObject::kMapOffset), |
| 8446 Immediate(Factory::fixed_array_map())); | 8453 Immediate(Factory::fixed_array_map())); |
| 8447 deferred->Branch(not_equal); | 8454 deferred->Branch(not_equal); |
| 8448 | 8455 |
| 8449 // Store the value. | 8456 // Store the value. |
| (...skipping 4475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12925 | 12932 |
| 12926 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 12933 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 12927 // tagged as a small integer. | 12934 // tagged as a small integer. |
| 12928 __ bind(&runtime); | 12935 __ bind(&runtime); |
| 12929 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 12936 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 12930 } | 12937 } |
| 12931 | 12938 |
| 12932 #undef __ | 12939 #undef __ |
| 12933 | 12940 |
| 12934 } } // namespace v8::internal | 12941 } } // namespace v8::internal |
| OLD | NEW |