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 6930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6941 if (cgen_->loop_nesting() > 0 && key_smi_analysis->IsLikelySmi()) { | 6941 if (cgen_->loop_nesting() > 0 && key_smi_analysis->IsLikelySmi()) { |
6942 Comment cmnt(masm, "[ Inlined store to keyed Property"); | 6942 Comment cmnt(masm, "[ Inlined store to keyed Property"); |
6943 | 6943 |
6944 // Get the receiver, key and value into registers. | 6944 // Get the receiver, key and value into registers. |
6945 Result value = cgen_->frame()->Pop(); | 6945 Result value = cgen_->frame()->Pop(); |
6946 Result key = cgen_->frame()->Pop(); | 6946 Result key = cgen_->frame()->Pop(); |
6947 Result receiver = cgen_->frame()->Pop(); | 6947 Result receiver = cgen_->frame()->Pop(); |
6948 | 6948 |
6949 Result tmp = cgen_->allocator_->Allocate(); | 6949 Result tmp = cgen_->allocator_->Allocate(); |
6950 ASSERT(tmp.is_valid()); | 6950 ASSERT(tmp.is_valid()); |
| 6951 Result tmp2 = cgen_->allocator_->Allocate(); |
| 6952 ASSERT(tmp2.is_valid()); |
6951 | 6953 |
6952 // Determine whether the value is a constant before putting it | 6954 // Determine whether the value is a constant before putting it |
6953 // in a register. | 6955 // in a register. |
6954 bool value_is_constant = value.is_constant(); | 6956 bool value_is_constant = value.is_constant(); |
6955 | 6957 |
6956 // Make sure that value, key and receiver are in registers. | 6958 // Make sure that value, key and receiver are in registers. |
6957 value.ToRegister(); | 6959 value.ToRegister(); |
6958 key.ToRegister(); | 6960 key.ToRegister(); |
6959 receiver.ToRegister(); | 6961 receiver.ToRegister(); |
6960 | 6962 |
6961 DeferredReferenceSetKeyedValue* deferred = | 6963 DeferredReferenceSetKeyedValue* deferred = |
6962 new DeferredReferenceSetKeyedValue(value.reg(), | 6964 new DeferredReferenceSetKeyedValue(value.reg(), |
6963 key.reg(), | 6965 key.reg(), |
6964 receiver.reg()); | 6966 receiver.reg()); |
6965 | 6967 |
6966 // Check that the value is a smi if it is not a constant. | |
6967 // We can skip the write barrier for smis and constants. | |
6968 if (!value_is_constant) { | |
6969 __ JumpIfNotSmi(value.reg(), deferred->entry_label()); | |
6970 } | |
6971 | |
6972 // Check that the key is a non-negative smi. | |
6973 __ JumpIfNotPositiveSmi(key.reg(), deferred->entry_label()); | |
6974 | |
6975 // Check that the receiver is not a smi. | 6968 // Check that the receiver is not a smi. |
6976 __ JumpIfSmi(receiver.reg(), deferred->entry_label()); | 6969 __ JumpIfSmi(receiver.reg(), deferred->entry_label()); |
6977 | 6970 |
| 6971 // Check that the key is a smi. |
| 6972 if (!key.is_smi()) { |
| 6973 __ JumpIfNotSmi(key.reg(), deferred->entry_label()); |
| 6974 } else { |
| 6975 if (FLAG_debug_code) { |
| 6976 __ AbortIfNotSmi(key.reg(), "Non-smi value in smi-typed value."); |
| 6977 } |
| 6978 } |
| 6979 |
6978 // Check that the receiver is a JSArray. | 6980 // Check that the receiver is a JSArray. |
6979 __ CmpObjectType(receiver.reg(), JS_ARRAY_TYPE, kScratchRegister); | 6981 __ CmpObjectType(receiver.reg(), JS_ARRAY_TYPE, kScratchRegister); |
6980 deferred->Branch(not_equal); | 6982 deferred->Branch(not_equal); |
6981 | 6983 |
6982 // Check that the key is within bounds. Both the key and the | 6984 // Check that the key is within bounds. Both the key and the |
6983 // length of the JSArray are smis. | 6985 // length of the JSArray are smis. Use unsigned comparison to handle |
| 6986 // negative keys. |
6984 __ SmiCompare(FieldOperand(receiver.reg(), JSArray::kLengthOffset), | 6987 __ SmiCompare(FieldOperand(receiver.reg(), JSArray::kLengthOffset), |
6985 key.reg()); | 6988 key.reg()); |
6986 deferred->Branch(less_equal); | 6989 deferred->Branch(below_equal); |
6987 | 6990 |
6988 // Get the elements array from the receiver and check that it | 6991 // Get the elements array from the receiver and check that it |
6989 // is a flat array (not a dictionary). | 6992 // is a flat array (not a dictionary). |
6990 __ movq(tmp.reg(), | 6993 __ movq(tmp.reg(), |
6991 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); | 6994 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); |
| 6995 |
| 6996 // Check whether it is possible to omit the write barrier. If the |
| 6997 // elements array is in new space or the value written is a smi we can |
| 6998 // safely update the elements array without updating the remembered set. |
| 6999 Label in_new_space; |
| 7000 __ InNewSpace(tmp.reg(), tmp2.reg(), equal, &in_new_space); |
| 7001 if (!value_is_constant) { |
| 7002 __ JumpIfNotSmi(value.reg(), deferred->entry_label()); |
| 7003 } |
| 7004 |
| 7005 __ bind(&in_new_space); |
6992 // Bind the deferred code patch site to be able to locate the | 7006 // Bind the deferred code patch site to be able to locate the |
6993 // fixed array map comparison. When debugging, we patch this | 7007 // fixed array map comparison. When debugging, we patch this |
6994 // comparison to always fail so that we will hit the IC call | 7008 // comparison to always fail so that we will hit the IC call |
6995 // in the deferred code which will allow the debugger to | 7009 // in the deferred code which will allow the debugger to |
6996 // break for fast case stores. | 7010 // break for fast case stores. |
6997 __ bind(deferred->patch_site()); | 7011 __ bind(deferred->patch_site()); |
6998 // Avoid using __ to ensure the distance from patch_site | 7012 // Avoid using __ to ensure the distance from patch_site |
6999 // to the map address is always the same. | 7013 // to the map address is always the same. |
7000 masm->movq(kScratchRegister, Factory::fixed_array_map(), | 7014 masm->movq(kScratchRegister, Factory::fixed_array_map(), |
7001 RelocInfo::EMBEDDED_OBJECT); | 7015 RelocInfo::EMBEDDED_OBJECT); |
(...skipping 3875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10877 // Call the function from C++. | 10891 // Call the function from C++. |
10878 return FUNCTION_CAST<ModuloFunction>(buffer); | 10892 return FUNCTION_CAST<ModuloFunction>(buffer); |
10879 } | 10893 } |
10880 | 10894 |
10881 #endif | 10895 #endif |
10882 | 10896 |
10883 | 10897 |
10884 #undef __ | 10898 #undef __ |
10885 | 10899 |
10886 } } // namespace v8::internal | 10900 } } // namespace v8::internal |
OLD | NEW |