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

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

Issue 647018: Introduce 'trivial' expressions, use them for this property assignments. (Closed)
Patch Set: Created 10 years, 10 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
« no previous file with comments | « src/ast.h ('k') | src/ia32/virtual-frame-ia32.h » ('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 4744 matching lines...) Expand 10 before | Expand all | Expand 10 after
4755 4755
4756 void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) { 4756 void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
4757 #ifdef DEBUG 4757 #ifdef DEBUG
4758 int original_height = frame()->height(); 4758 int original_height = frame()->height();
4759 #endif 4759 #endif
4760 Comment cmnt(masm(), "[ Named Property Assignment"); 4760 Comment cmnt(masm(), "[ Named Property Assignment");
4761 Variable* var = node->target()->AsVariableProxy()->AsVariable(); 4761 Variable* var = node->target()->AsVariableProxy()->AsVariable();
4762 Property* prop = node->target()->AsProperty(); 4762 Property* prop = node->target()->AsProperty();
4763 ASSERT(var == NULL || (prop == NULL && var->is_global())); 4763 ASSERT(var == NULL || (prop == NULL && var->is_global()));
4764 4764
4765 // Initialize name and evaluate the receiver subexpression. 4765 // Initialize name and evaluate the receiver subexpression if necessary.
4766 Handle<String> name; 4766 Handle<String> name;
4767 bool is_trivial_receiver = false;
4767 if (var != NULL) { 4768 if (var != NULL) {
4768 name = var->name(); 4769 name = var->name();
4769 LoadGlobal(); 4770 LoadGlobal();
4770 } else { 4771 } else {
4771 Literal* lit = prop->key()->AsLiteral(); 4772 Literal* lit = prop->key()->AsLiteral();
4772 ASSERT(lit != NULL); 4773 ASSERT(lit != NULL);
4773 name = Handle<String>::cast(lit->handle()); 4774 name = Handle<String>::cast(lit->handle());
4774 Load(prop->obj()); 4775 // Do not materialize the receiver on the frame if it is trivial.
4776 is_trivial_receiver = prop->obj()->IsTrivial();
4777 if (!is_trivial_receiver) Load(prop->obj());
4775 } 4778 }
4776 4779
4777 if (node->starts_initialization_block()) { 4780 if (node->starts_initialization_block()) {
4778 // Change to slow case in the beginning of an initialization block to 4781 // Change to slow case in the beginning of an initialization block to
4779 // avoid the quadratic behavior of repeatedly adding fast properties. 4782 // avoid the quadratic behavior of repeatedly adding fast properties.
4780 frame()->Dup(); 4783 if (is_trivial_receiver) {
4784 frame()->Push(prop->obj());
4785 } else {
4786 frame()->Dup();
4787 }
4781 Result ignored = frame()->CallRuntime(Runtime::kToSlowProperties, 1); 4788 Result ignored = frame()->CallRuntime(Runtime::kToSlowProperties, 1);
4782 } 4789 }
4783 4790
4784 if (node->ends_initialization_block()) { 4791 if (node->ends_initialization_block() && !is_trivial_receiver) {
4785 // Add an extra copy of the receiver to the frame, so that it can be 4792 // Add an extra copy of the receiver to the frame, so that it can be
4786 // converted back to fast case after the assignment. 4793 // converted back to fast case after the assignment.
4787 frame()->Dup(); 4794 frame()->Dup();
4788 } 4795 }
4789 4796
4790 // Evaluate the right-hand side. 4797 // Evaluate the right-hand side.
4791 if (node->is_compound()) { 4798 if (node->is_compound()) {
4792 frame()->Dup(); 4799 if (is_trivial_receiver) {
4800 frame()->Push(prop->obj());
4801 } else {
4802 frame()->Dup();
4803 }
4793 Result value = EmitNamedLoad(name, var != NULL); 4804 Result value = EmitNamedLoad(name, var != NULL);
4794 frame()->Push(&value); 4805 frame()->Push(&value);
4795 Load(node->value()); 4806 Load(node->value());
4796 4807
4797 bool overwrite_value = 4808 bool overwrite_value =
4798 (node->value()->AsBinaryOperation() != NULL && 4809 (node->value()->AsBinaryOperation() != NULL &&
4799 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 4810 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
4800 GenericBinaryOperation(node->binary_op(), 4811 GenericBinaryOperation(node->binary_op(),
4801 node->type(), 4812 node->type(),
4802 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); 4813 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
4803 } else { 4814 } else {
4804 Load(node->value()); 4815 Load(node->value());
4805 } 4816 }
4806 4817
4807 // Perform the assignment. It is safe to ignore constants here. 4818 // Perform the assignment. It is safe to ignore constants here.
4808 ASSERT(var == NULL || var->mode() != Variable::CONST); 4819 ASSERT(var == NULL || var->mode() != Variable::CONST);
4809 ASSERT(node->op() != Token::INIT_CONST); 4820 ASSERT(node->op() != Token::INIT_CONST);
4821 if (is_trivial_receiver) {
4822 Result value = frame()->Pop();
4823 frame()->Push(prop->obj());
4824 frame()->Push(&value);
4825 }
4810 CodeForSourcePosition(node->position()); 4826 CodeForSourcePosition(node->position());
4811 Result answer = EmitNamedStore(name); 4827 Result answer = EmitNamedStore(name);
4812 frame()->Push(&answer); 4828 frame()->Push(&answer);
4813 4829
4814 if (node->ends_initialization_block()) { 4830 if (node->ends_initialization_block()) {
4815 // The argument to the runtime call is the extra copy of the receiver, 4831 // The argument to the runtime call is the receiver.
4816 // which is below the value of the assignment. Swap the receiver and 4832 if (is_trivial_receiver) {
4817 // the value of the assignment expression. 4833 frame()->Push(prop->obj());
4818 Result result = frame()->Pop(); 4834 } else {
4819 Result receiver = frame()->Pop(); 4835 // A copy of the receiver is below the value of the assignment. Swap
4820 frame()->Push(&result); 4836 // the receiver and the value of the assignment expression.
4821 frame()->Push(&receiver); 4837 Result result = frame()->Pop();
4838 Result receiver = frame()->Pop();
4839 frame()->Push(&result);
4840 frame()->Push(&receiver);
4841 }
4822 Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1); 4842 Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1);
4823 } 4843 }
4824 4844
4825 ASSERT(frame()->height() == original_height + 1); 4845 ASSERT(frame()->height() == original_height + 1);
4826 } 4846 }
4827 4847
4828 4848
4829 void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) { 4849 void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) {
4830 #ifdef DEBUG 4850 #ifdef DEBUG
4831 int original_height = frame()->height(); 4851 int original_height = frame()->height();
(...skipping 5904 matching lines...) Expand 10 before | Expand all | Expand 10 after
10736 10756
10737 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 10757 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
10738 // tagged as a small integer. 10758 // tagged as a small integer.
10739 __ bind(&runtime); 10759 __ bind(&runtime);
10740 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); 10760 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1);
10741 } 10761 }
10742 10762
10743 #undef __ 10763 #undef __
10744 10764
10745 } } // namespace v8::internal 10765 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ast.h ('k') | src/ia32/virtual-frame-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698