OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 3857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3868 // Push the result. | 3868 // Push the result. |
3869 frame->Push(eax); | 3869 frame->Push(eax); |
3870 break; | 3870 break; |
3871 } | 3871 } |
3872 | 3872 |
3873 case KEYED: { | 3873 case KEYED: { |
3874 // TODO(1241834): Make sure that it is safe to ignore the | 3874 // TODO(1241834): Make sure that it is safe to ignore the |
3875 // distinction between expressions in a typeof and not in a | 3875 // distinction between expressions in a typeof and not in a |
3876 // typeof. | 3876 // typeof. |
3877 Variable* var = expression_->AsVariableProxy()->AsVariable(); | 3877 Variable* var = expression_->AsVariableProxy()->AsVariable(); |
| 3878 bool is_global = var != NULL; |
| 3879 ASSERT(!is_global || var->is_global()); |
3878 // Inline array load code if inside of a loop. We do not know | 3880 // Inline array load code if inside of a loop. We do not know |
3879 // the receiver map yet, so we initially generate the code with | 3881 // the receiver map yet, so we initially generate the code with |
3880 // a check against an invalid map. In the inline cache code, we | 3882 // a check against an invalid map. In the inline cache code, we |
3881 // patch the map check if appropriate. | 3883 // patch the map check if appropriate. |
3882 if (cgen_->loop_nesting() > 0) { | 3884 if (cgen_->loop_nesting() > 0) { |
3883 Comment cmnt(masm, "[ Inlined array index load"); | 3885 Comment cmnt(masm, "[ Inlined array index load"); |
3884 DeferredReferenceGetKeyedValue* deferred = | 3886 DeferredReferenceGetKeyedValue* deferred = |
3885 new DeferredReferenceGetKeyedValue(cgen_, var != NULL); | 3887 new DeferredReferenceGetKeyedValue(cgen_, is_global); |
3886 // Load receiver and check that it is not a smi (only needed | 3888 // Load receiver and check that it is not a smi (only needed |
3887 // if not contextual) and that it has the expected map. | 3889 // if this is not a load from the global context) and that it |
| 3890 // has the expected map. |
3888 __ mov(edx, Operand(esp, kPointerSize)); | 3891 __ mov(edx, Operand(esp, kPointerSize)); |
3889 if (var == NULL) { | 3892 if (!is_global) { |
3890 __ test(edx, Immediate(kSmiTagMask)); | 3893 __ test(edx, Immediate(kSmiTagMask)); |
3891 __ j(zero, deferred->enter(), not_taken); | 3894 __ j(zero, deferred->enter(), not_taken); |
3892 } | 3895 } |
3893 // Initially, use an invalid map. The map is patched in the IC | 3896 // Initially, use an invalid map. The map is patched in the IC |
3894 // initialization code. | 3897 // initialization code. |
3895 __ bind(deferred->patch_site()); | 3898 __ bind(deferred->patch_site()); |
3896 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 3899 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), |
3897 Immediate(Factory::null_value())); | 3900 Immediate(Factory::null_value())); |
3898 __ j(not_equal, deferred->enter(), not_taken); | 3901 __ j(not_equal, deferred->enter(), not_taken); |
3899 // Load key and check that it is a smi. | 3902 // Load key and check that it is a smi. |
(...skipping 14 matching lines...) Expand all Loading... |
3914 // Load and check that the result is not the hole. | 3917 // Load and check that the result is not the hole. |
3915 __ mov(eax, | 3918 __ mov(eax, |
3916 Operand(edx, eax, times_4, Array::kHeaderSize - kHeapObjectTag)); | 3919 Operand(edx, eax, times_4, Array::kHeaderSize - kHeapObjectTag)); |
3917 __ cmp(Operand(eax), Immediate(Factory::the_hole_value())); | 3920 __ cmp(Operand(eax), Immediate(Factory::the_hole_value())); |
3918 __ j(equal, deferred->enter(), not_taken); | 3921 __ j(equal, deferred->enter(), not_taken); |
3919 __ IncrementCounter(&Counters::keyed_load_inline, 1); | 3922 __ IncrementCounter(&Counters::keyed_load_inline, 1); |
3920 __ bind(deferred->exit()); | 3923 __ bind(deferred->exit()); |
3921 } else { | 3924 } else { |
3922 Comment cmnt(masm, "[ Load from keyed Property"); | 3925 Comment cmnt(masm, "[ Load from keyed Property"); |
3923 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 3926 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
3924 if (var != NULL) { | 3927 if (is_global) { |
3925 ASSERT(var->is_global()); | |
3926 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 3928 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
3927 } else { | 3929 } else { |
3928 __ call(ic, RelocInfo::CODE_TARGET); | 3930 __ call(ic, RelocInfo::CODE_TARGET); |
3929 } | 3931 } |
3930 // Make sure that we do not have a test instruction after the | 3932 // Make sure that we do not have a test instruction after the |
3931 // call. A test instruction after the call is used to | 3933 // call. A test instruction after the call is used to |
3932 // indicate that we have generated an inline version of the | 3934 // indicate that we have generated an inline version of the |
3933 // keyed load. The explicit nop instruction is here because | 3935 // keyed load. The explicit nop instruction is here because |
3934 // the push that follows might be peep-hole optimized away. | 3936 // the push that follows might be peep-hole optimized away. |
3935 __ nop(); | 3937 __ nop(); |
(...skipping 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5275 | 5277 |
5276 // Slow-case: Go through the JavaScript implementation. | 5278 // Slow-case: Go through the JavaScript implementation. |
5277 __ bind(&slow); | 5279 __ bind(&slow); |
5278 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 5280 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
5279 } | 5281 } |
5280 | 5282 |
5281 | 5283 |
5282 #undef __ | 5284 #undef __ |
5283 | 5285 |
5284 } } // namespace v8::internal | 5286 } } // namespace v8::internal |
OLD | NEW |