Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 3046006: Inline in-object property stores when in loop and not in top-level (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/ic-arm.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 5322 matching lines...) Expand 10 before | Expand all | Expand 10 after
5333 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 5333 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
5334 if (CompileTimeValue::IsCompileTimeValue(property->value())) break; 5334 if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
5335 // else fall through. 5335 // else fall through.
5336 case ObjectLiteral::Property::COMPUTED: { 5336 case ObjectLiteral::Property::COMPUTED: {
5337 Handle<Object> key(property->key()->handle()); 5337 Handle<Object> key(property->key()->handle());
5338 if (key->IsSymbol()) { 5338 if (key->IsSymbol()) {
5339 // Duplicate the object as the IC receiver. 5339 // Duplicate the object as the IC receiver.
5340 frame_->Dup(); 5340 frame_->Dup();
5341 Load(property->value()); 5341 Load(property->value());
5342 Result dummy = frame_->CallStoreIC(Handle<String>::cast(key), false); 5342 Result dummy = frame_->CallStoreIC(Handle<String>::cast(key), false);
5343 // A test eax instruction following the store IC call would
5344 // indicate the presence of an inlined version of the
5345 // store. Add a nop to indicate that there is no such
5346 // inlined version.
5347 __ nop();
5343 dummy.Unuse(); 5348 dummy.Unuse();
5344 break; 5349 break;
5345 } 5350 }
5346 // Fall through 5351 // Fall through
5347 } 5352 }
5348 case ObjectLiteral::Property::PROTOTYPE: { 5353 case ObjectLiteral::Property::PROTOTYPE: {
5349 // Duplicate the object as an argument to the runtime call. 5354 // Duplicate the object as an argument to the runtime call.
5350 frame_->Dup(); 5355 frame_->Dup();
5351 Load(property->key()); 5356 Load(property->key());
5352 Load(property->value()); 5357 Load(property->value());
(...skipping 3501 matching lines...) Expand 10 before | Expand all | Expand 10 after
8854 } 8859 }
8855 ASSERT(frame()->height() == original_height - 1); 8860 ASSERT(frame()->height() == original_height - 1);
8856 return result; 8861 return result;
8857 } 8862 }
8858 8863
8859 8864
8860 Result CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) { 8865 Result CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
8861 #ifdef DEBUG 8866 #ifdef DEBUG
8862 int expected_height = frame()->height() - (is_contextual ? 1 : 2); 8867 int expected_height = frame()->height() - (is_contextual ? 1 : 2);
8863 #endif 8868 #endif
8864 Result result = frame()->CallStoreIC(name, is_contextual); 8869
8870 Result result;
8871 if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
8872 result = frame()->CallStoreIC(name, is_contextual);
8873 // A test eax instruction following the call signals that the inobject
8874 // property case was inlined. Ensure that there is not a test eax
8875 // instruction here.
8876 __ nop();
8877 } else {
8878 // Inline the in-object property case.
8879 JumpTarget slow, done;
8880 Label patch_site;
8881
8882 // Get the value and receiver from the stack.
8883 Result value = frame()->Pop();
8884 value.ToRegister();
8885 Result receiver = frame()->Pop();
8886 receiver.ToRegister();
8887
8888 // Allocate result register.
8889 result = allocator()->Allocate();
8890 ASSERT(result.is_valid() && receiver.is_valid() && value.is_valid());
8891
8892 // Check that the receiver is a heap object.
8893 __ test(receiver.reg(), Immediate(kSmiTagMask));
8894 slow.Branch(zero, &value, &receiver);
8895
8896 // This is the map check instruction that will be patched (so we can't
8897 // use the double underscore macro that may insert instructions).
8898 // Initially use an invalid map to force a failure.
8899 __ bind(&patch_site);
8900 masm()->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
8901 Immediate(Factory::null_value()));
8902 // This branch is always a forwards branch so it's always a fixed size
8903 // which allows the assert below to succeed and patching to work.
8904 slow.Branch(not_equal, &value, &receiver);
8905
8906 // The delta from the patch label to the store offset must be
8907 // statically known.
8908 ASSERT(masm()->SizeOfCodeGeneratedSince(&patch_site) ==
8909 StoreIC::kOffsetToStoreInstruction);
8910
8911 // The initial (invalid) offset has to be large enough to force a 32-bit
8912 // instruction encoding to allow patching with an arbitrary offset. Use
8913 // kMaxInt (minus kHeapObjectTag).
8914 int offset = kMaxInt;
8915 __ mov(FieldOperand(receiver.reg(), offset), value.reg());
8916 __ mov(result.reg(), Operand(value.reg()));
8917
8918 // Allocate scratch register for write barrier.
8919 Result scratch = allocator()->Allocate();
8920 ASSERT(scratch.is_valid() &&
8921 result.is_valid() &&
8922 receiver.is_valid() &&
8923 value.is_valid());
8924
8925 // The write barrier clobbers all input registers, so spill the
8926 // receiver and the value.
8927 frame_->Spill(receiver.reg());
8928 frame_->Spill(value.reg());
8929
8930 // Update the write barrier. To save instructions in the inlined
8931 // version we do not filter smis.
8932 Label skip_write_barrier;
8933 __ InNewSpace(receiver.reg(), value.reg(), equal, &skip_write_barrier);
8934 int delta_to_record_write = masm_->SizeOfCodeGeneratedSince(&patch_site);
8935 __ lea(scratch.reg(), Operand(receiver.reg(), offset));
8936 __ RecordWriteHelper(receiver.reg(), scratch.reg(), value.reg());
8937 if (FLAG_debug_code) {
8938 __ mov(receiver.reg(), Immediate(BitCast<int32_t>(kZapValue)));
8939 __ mov(value.reg(), Immediate(BitCast<int32_t>(kZapValue)));
8940 __ mov(scratch.reg(), Immediate(BitCast<int32_t>(kZapValue)));
8941 }
8942 __ bind(&skip_write_barrier);
8943 value.Unuse();
8944 scratch.Unuse();
8945 receiver.Unuse();
8946 done.Jump(&result);
8947
8948 slow.Bind(&value, &receiver);
8949 frame()->Push(&receiver);
8950 frame()->Push(&value);
8951 result = frame()->CallStoreIC(name, is_contextual);
8952 // Encode the offset to the map check instruction and the offset
8953 // to the write barrier store address computation in a test eax
8954 // instruction.
8955 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site);
8956 __ test(eax,
8957 Immediate((delta_to_record_write << 16) | delta_to_patch_site));
8958 done.Bind(&result);
8959 }
8865 8960
8866 ASSERT_EQ(expected_height, frame()->height()); 8961 ASSERT_EQ(expected_height, frame()->height());
8867 return result; 8962 return result;
8868 } 8963 }
8869 8964
8870 8965
8871 Result CodeGenerator::EmitKeyedLoad() { 8966 Result CodeGenerator::EmitKeyedLoad() {
8872 #ifdef DEBUG 8967 #ifdef DEBUG
8873 int original_height = frame()->height(); 8968 int original_height = frame()->height();
8874 #endif 8969 #endif
(...skipping 4932 matching lines...) Expand 10 before | Expand all | Expand 10 after
13807 masm.GetCode(&desc); 13902 masm.GetCode(&desc);
13808 // Call the function from C++. 13903 // Call the function from C++.
13809 return FUNCTION_CAST<MemCopyFunction>(buffer); 13904 return FUNCTION_CAST<MemCopyFunction>(buffer);
13810 } 13905 }
13811 13906
13812 #undef __ 13907 #undef __
13813 13908
13814 } } // namespace v8::internal 13909 } } // namespace v8::internal
13815 13910
13816 #endif // V8_TARGET_ARCH_IA32 13911 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/arm/ic-arm.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698