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

Side by Side Diff: src/hydrogen.cc

Issue 7043003: Version 3.3.8 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 9 years, 7 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/hydrogen.h ('k') | src/hydrogen-instructions.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 1785 matching lines...) Expand 10 before | Expand all | Expand 10 after
1796 HValue* use_value = it.value(); 1796 HValue* use_value = it.value();
1797 int use_index = it.index(); 1797 int use_index = it.index();
1798 Representation req = use_value->RequiredInputRepresentation(use_index); 1798 Representation req = use_value->RequiredInputRepresentation(use_index);
1799 if (req.IsNone() || req.Equals(r)) continue; 1799 if (req.IsNone() || req.Equals(r)) continue;
1800 InsertRepresentationChangeForUse(value, use_value, use_index, req); 1800 InsertRepresentationChangeForUse(value, use_value, use_index, req);
1801 } 1801 }
1802 if (value->HasNoUses()) { 1802 if (value->HasNoUses()) {
1803 ASSERT(value->IsConstant()); 1803 ASSERT(value->IsConstant());
1804 value->DeleteAndReplaceWith(NULL); 1804 value->DeleteAndReplaceWith(NULL);
1805 } 1805 }
1806
1807 // The only purpose of a HForceRepresentation is to represent the value
1808 // after the (possible) HChange instruction. We make it disappear.
1809 if (value->IsForceRepresentation()) {
1810 value->DeleteAndReplaceWith(HForceRepresentation::cast(value)->value());
1811 }
1806 } 1812 }
1807 1813
1808 1814
1809 void HGraph::InsertRepresentationChanges() { 1815 void HGraph::InsertRepresentationChanges() {
1810 HPhase phase("Insert representation changes", this); 1816 HPhase phase("Insert representation changes", this);
1811 1817
1812 1818
1813 // Compute truncation flag for phis: Initially assume that all 1819 // Compute truncation flag for phis: Initially assume that all
1814 // int32-phis allow truncation and iteratively remove the ones that 1820 // int32-phis allow truncation and iteratively remove the ones that
1815 // are used in an operation that does not allow a truncating 1821 // are used in an operation that does not allow a truncating
(...skipping 1902 matching lines...) Expand 10 before | Expand all | Expand 10 after
3718 ASSERT(map->has_external_array_elements()); 3724 ASSERT(map->has_external_array_elements());
3719 AddInstruction(new(zone()) HCheckMap(object, map)); 3725 AddInstruction(new(zone()) HCheckMap(object, map));
3720 HLoadElements* elements = new(zone()) HLoadElements(object); 3726 HLoadElements* elements = new(zone()) HLoadElements(object);
3721 AddInstruction(elements); 3727 AddInstruction(elements);
3722 HInstruction* length = AddInstruction( 3728 HInstruction* length = AddInstruction(
3723 new(zone()) HExternalArrayLength(elements)); 3729 new(zone()) HExternalArrayLength(elements));
3724 AddInstruction(new(zone()) HBoundsCheck(key, length)); 3730 AddInstruction(new(zone()) HBoundsCheck(key, length));
3725 HLoadExternalArrayPointer* external_elements = 3731 HLoadExternalArrayPointer* external_elements =
3726 new(zone()) HLoadExternalArrayPointer(elements); 3732 new(zone()) HLoadExternalArrayPointer(elements);
3727 AddInstruction(external_elements); 3733 AddInstruction(external_elements);
3734 if (expr->external_array_type() == kExternalPixelArray) {
3735 HClampToUint8* clamp = new(zone()) HClampToUint8(val);
3736 AddInstruction(clamp);
3737 val = clamp;
3738 }
3728 return new(zone()) HStoreKeyedSpecializedArrayElement( 3739 return new(zone()) HStoreKeyedSpecializedArrayElement(
3729 external_elements, 3740 external_elements,
3730 key, 3741 key,
3731 val, 3742 val,
3732 expr->external_array_type()); 3743 expr->external_array_type());
3733 } 3744 }
3734 3745
3735 3746
3736 HInstruction* HGraphBuilder::BuildStoreKeyed(HValue* object, 3747 HInstruction* HGraphBuilder::BuildStoreKeyed(HValue* object,
3737 HValue* key, 3748 HValue* key,
(...skipping 949 matching lines...) Expand 10 before | Expand all | Expand 10 after
4687 materialize_true = NULL; 4698 materialize_true = NULL;
4688 } 4699 }
4689 4700
4690 HBasicBlock* join = 4701 HBasicBlock* join =
4691 CreateJoin(materialize_false, materialize_true, expr->id()); 4702 CreateJoin(materialize_false, materialize_true, expr->id());
4692 set_current_block(join); 4703 set_current_block(join);
4693 if (join != NULL) ast_context()->ReturnValue(Pop()); 4704 if (join != NULL) ast_context()->ReturnValue(Pop());
4694 } 4705 }
4695 4706
4696 4707
4697 HInstruction* HGraphBuilder::BuildIncrement(HValue* value, 4708 HInstruction* HGraphBuilder::BuildIncrement(bool returns_original_input,
4698 bool increment,
4699 CountOperation* expr) { 4709 CountOperation* expr) {
4700 HConstant* delta = increment 4710 // The input to the count operation is on top of the expression stack.
4701 ? graph_->GetConstant1()
4702 : graph_->GetConstantMinus1();
4703 HInstruction* instr = new(zone()) HAdd(value, delta);
4704 TypeInfo info = oracle()->IncrementType(expr); 4711 TypeInfo info = oracle()->IncrementType(expr);
4705 Representation rep = ToRepresentation(info); 4712 Representation rep = ToRepresentation(info);
4706 if (rep.IsTagged()) { 4713 if (rep.IsTagged()) {
4707 rep = Representation::Integer32(); 4714 rep = Representation::Integer32();
4708 } 4715 }
4716
4717 if (returns_original_input) {
4718 // We need an explicit HValue representing ToNumber(input). The
4719 // actual HChange instruction we need is (sometimes) added in a later
4720 // phase, so it is not available now to be used as an input to HAdd and
4721 // as the return value.
4722 HInstruction* number_input = new(zone()) HForceRepresentation(Pop(), rep);
4723 AddInstruction(number_input);
4724 Push(number_input);
4725 }
4726
4727 // The addition has no side effects, so we do not need
4728 // to simulate the expression stack after this instruction.
4729 // Any later failures deopt to the load of the input or earlier.
4730 HConstant* delta = (expr->op() == Token::INC)
4731 ? graph_->GetConstant1()
4732 : graph_->GetConstantMinus1();
4733 HInstruction* instr = new(zone()) HAdd(Top(), delta);
4709 TraceRepresentation(expr->op(), info, instr, rep); 4734 TraceRepresentation(expr->op(), info, instr, rep);
4710 instr->AssumeRepresentation(rep); 4735 instr->AssumeRepresentation(rep);
4736 AddInstruction(instr);
4711 return instr; 4737 return instr;
4712 } 4738 }
4713 4739
4714 4740
4715 void HGraphBuilder::VisitCountOperation(CountOperation* expr) { 4741 void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
4716 ASSERT(!HasStackOverflow()); 4742 ASSERT(!HasStackOverflow());
4717 ASSERT(current_block() != NULL); 4743 ASSERT(current_block() != NULL);
4718 ASSERT(current_block()->HasPredecessor()); 4744 ASSERT(current_block()->HasPredecessor());
4719 Expression* target = expr->expression(); 4745 Expression* target = expr->expression();
4720 VariableProxy* proxy = target->AsVariableProxy(); 4746 VariableProxy* proxy = target->AsVariableProxy();
4721 Variable* var = proxy->AsVariable(); 4747 Variable* var = proxy->AsVariable();
4722 Property* prop = target->AsProperty(); 4748 Property* prop = target->AsProperty();
4723 ASSERT(var == NULL || prop == NULL); 4749 if (var == NULL && prop == NULL) {
4724 bool inc = expr->op() == Token::INC; 4750 return Bailout("invalid lhs in count operation");
4751 }
4752
4753 // Match the full code generator stack by simulating an extra stack
4754 // element for postfix operations in a non-effect context. The return
4755 // value is ToNumber(input).
4756 bool returns_original_input =
4757 expr->is_postfix() && !ast_context()->IsEffect();
4758 HValue* input = NULL; // ToNumber(original_input).
4759 HValue* after = NULL; // The result after incrementing or decrementing.
4725 4760
4726 if (var != NULL) { 4761 if (var != NULL) {
4762 // Argument of the count operation is a variable, not a property.
4763 ASSERT(prop == NULL);
4727 CHECK_ALIVE(VisitForValue(target)); 4764 CHECK_ALIVE(VisitForValue(target));
4728 4765
4729 // Match the full code generator stack by simulating an extra stack 4766 after = BuildIncrement(returns_original_input, expr);
4730 // element for postfix operations in a non-effect context. 4767 input = returns_original_input ? Top() : Pop();
4731 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect();
4732 HValue* before = has_extra ? Top() : Pop();
4733 HInstruction* after = BuildIncrement(before, inc, expr);
4734 AddInstruction(after);
4735 Push(after); 4768 Push(after);
4736 4769
4737 if (var->is_global()) { 4770 if (var->is_global()) {
4738 HandleGlobalVariableAssignment(var, 4771 HandleGlobalVariableAssignment(var,
4739 after, 4772 after,
4740 expr->position(), 4773 expr->position(),
4741 expr->AssignmentId()); 4774 expr->AssignmentId());
4742 } else if (var->IsStackAllocated()) { 4775 } else if (var->IsStackAllocated()) {
4743 Bind(var, after); 4776 Bind(var, after);
4744 } else if (var->IsContextSlot()) { 4777 } else if (var->IsContextSlot()) {
4745 HValue* context = BuildContextChainWalk(var); 4778 HValue* context = BuildContextChainWalk(var);
4746 int index = var->AsSlot()->index(); 4779 int index = var->AsSlot()->index();
4747 HStoreContextSlot* instr = 4780 HStoreContextSlot* instr =
4748 new(zone()) HStoreContextSlot(context, index, after); 4781 new(zone()) HStoreContextSlot(context, index, after);
4749 AddInstruction(instr); 4782 AddInstruction(instr);
4750 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); 4783 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
4751 } else { 4784 } else {
4752 return Bailout("lookup variable in count operation"); 4785 return Bailout("lookup variable in count operation");
4753 } 4786 }
4754 Drop(has_extra ? 2 : 1);
4755 ast_context()->ReturnValue(expr->is_postfix() ? before : after);
4756 4787
4757 } else if (prop != NULL) { 4788 } else {
4789 // Argument of the count operation is a property.
4790 ASSERT(prop != NULL);
4758 prop->RecordTypeFeedback(oracle()); 4791 prop->RecordTypeFeedback(oracle());
4759 4792
4760 if (prop->key()->IsPropertyName()) { 4793 if (prop->key()->IsPropertyName()) {
4761 // Named property. 4794 // Named property.
4762 4795 if (returns_original_input) Push(graph_->GetConstantUndefined());
4763 // Match the full code generator stack by simulating an extra stack
4764 // element for postfix operations in a non-effect context.
4765 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect();
4766 if (has_extra) Push(graph_->GetConstantUndefined());
4767 4796
4768 CHECK_ALIVE(VisitForValue(prop->obj())); 4797 CHECK_ALIVE(VisitForValue(prop->obj()));
4769 HValue* obj = Top(); 4798 HValue* obj = Top();
4770 4799
4771 HInstruction* load = NULL; 4800 HInstruction* load = NULL;
4772 if (prop->IsMonomorphic()) { 4801 if (prop->IsMonomorphic()) {
4773 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 4802 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
4774 Handle<Map> map = prop->GetReceiverTypes()->first(); 4803 Handle<Map> map = prop->GetReceiverTypes()->first();
4775 load = BuildLoadNamed(obj, prop, map, name); 4804 load = BuildLoadNamed(obj, prop, map, name);
4776 } else { 4805 } else {
4777 load = BuildLoadNamedGeneric(obj, prop); 4806 load = BuildLoadNamedGeneric(obj, prop);
4778 } 4807 }
4779 PushAndAdd(load); 4808 PushAndAdd(load);
4780 if (load->HasSideEffects()) AddSimulate(expr->CountId()); 4809 if (load->HasSideEffects()) AddSimulate(expr->CountId());
4781 4810
4782 HValue* before = Pop(); 4811 after = BuildIncrement(returns_original_input, expr);
4783 // There is no deoptimization to after the increment, so we don't need 4812 input = Pop();
4784 // to simulate the expression stack after this instruction.
4785 HInstruction* after = BuildIncrement(before, inc, expr);
4786 AddInstruction(after);
4787 4813
4788 HInstruction* store = BuildStoreNamed(obj, after, prop); 4814 HInstruction* store = BuildStoreNamed(obj, after, prop);
4789 AddInstruction(store); 4815 AddInstruction(store);
4790 4816
4791 // Overwrite the receiver in the bailout environment with the result 4817 // Overwrite the receiver in the bailout environment with the result
4792 // of the operation, and the placeholder with the original value if 4818 // of the operation, and the placeholder with the original value if
4793 // necessary. 4819 // necessary.
4794 environment()->SetExpressionStackAt(0, after); 4820 environment()->SetExpressionStackAt(0, after);
4795 if (has_extra) environment()->SetExpressionStackAt(1, before); 4821 if (returns_original_input) environment()->SetExpressionStackAt(1, input);
4796 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); 4822 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId());
4797 Drop(has_extra ? 2 : 1);
4798
4799 ast_context()->ReturnValue(expr->is_postfix() ? before : after);
4800 4823
4801 } else { 4824 } else {
4802 // Keyed property. 4825 // Keyed property.
4803 4826 if (returns_original_input) Push(graph_->GetConstantUndefined());
4804 // Match the full code generator stack by simulate an extra stack element
4805 // for postfix operations in a non-effect context.
4806 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect();
4807 if (has_extra) Push(graph_->GetConstantUndefined());
4808 4827
4809 CHECK_ALIVE(VisitForValue(prop->obj())); 4828 CHECK_ALIVE(VisitForValue(prop->obj()));
4810 CHECK_ALIVE(VisitForValue(prop->key())); 4829 CHECK_ALIVE(VisitForValue(prop->key()));
4811 HValue* obj = environment()->ExpressionStackAt(1); 4830 HValue* obj = environment()->ExpressionStackAt(1);
4812 HValue* key = environment()->ExpressionStackAt(0); 4831 HValue* key = environment()->ExpressionStackAt(0);
4813 4832
4814 HInstruction* load = BuildLoadKeyed(obj, key, prop); 4833 HInstruction* load = BuildLoadKeyed(obj, key, prop);
4815 PushAndAdd(load); 4834 PushAndAdd(load);
4816 if (load->HasSideEffects()) AddSimulate(expr->CountId()); 4835 if (load->HasSideEffects()) AddSimulate(expr->CountId());
4817 4836
4818 HValue* before = Pop(); 4837 after = BuildIncrement(returns_original_input, expr);
4819 // There is no deoptimization to after the increment, so we don't need 4838 input = Pop();
4820 // to simulate the expression stack after this instruction.
4821 HInstruction* after = BuildIncrement(before, inc, expr);
4822 AddInstruction(after);
4823 4839
4824 expr->RecordTypeFeedback(oracle()); 4840 expr->RecordTypeFeedback(oracle());
4825 HInstruction* store = BuildStoreKeyed(obj, key, after, expr); 4841 HInstruction* store = BuildStoreKeyed(obj, key, after, expr);
4826 AddInstruction(store); 4842 AddInstruction(store);
4827 4843
4828 // Drop the key from the bailout environment. Overwrite the receiver 4844 // Drop the key from the bailout environment. Overwrite the receiver
4829 // with the result of the operation, and the placeholder with the 4845 // with the result of the operation, and the placeholder with the
4830 // original value if necessary. 4846 // original value if necessary.
4831 Drop(1); 4847 Drop(1);
4832 environment()->SetExpressionStackAt(0, after); 4848 environment()->SetExpressionStackAt(0, after);
4833 if (has_extra) environment()->SetExpressionStackAt(1, before); 4849 if (returns_original_input) environment()->SetExpressionStackAt(1, input);
4834 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); 4850 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId());
4835 Drop(has_extra ? 2 : 1); 4851 }
4852 }
4836 4853
4837 ast_context()->ReturnValue(expr->is_postfix() ? before : after); 4854 Drop(returns_original_input ? 2 : 1);
4838 } 4855 ast_context()->ReturnValue(expr->is_postfix() ? input : after);
4839
4840 } else {
4841 return Bailout("invalid lhs in count operation");
4842 }
4843 } 4856 }
4844 4857
4845 4858
4846 HCompareSymbolEq* HGraphBuilder::BuildSymbolCompare(HValue* left, 4859 HCompareSymbolEq* HGraphBuilder::BuildSymbolCompare(HValue* left,
4847 HValue* right, 4860 HValue* right,
4848 Token::Value op) { 4861 Token::Value op) {
4849 ASSERT(op == Token::EQ || op == Token::EQ_STRICT); 4862 ASSERT(op == Token::EQ || op == Token::EQ_STRICT);
4850 AddInstruction(new(zone()) HCheckNonSmi(left)); 4863 AddInstruction(new(zone()) HCheckNonSmi(left));
4851 AddInstruction(HCheckInstanceType::NewIsSymbol(left)); 4864 AddInstruction(HCheckInstanceType::NewIsSymbol(left));
4852 AddInstruction(new(zone()) HCheckNonSmi(right)); 4865 AddInstruction(new(zone()) HCheckNonSmi(right));
(...skipping 1276 matching lines...) Expand 10 before | Expand all | Expand 10 after
6129 } 6142 }
6130 } 6143 }
6131 6144
6132 #ifdef DEBUG 6145 #ifdef DEBUG
6133 if (graph_ != NULL) graph_->Verify(); 6146 if (graph_ != NULL) graph_->Verify();
6134 if (allocator_ != NULL) allocator_->Verify(); 6147 if (allocator_ != NULL) allocator_->Verify();
6135 #endif 6148 #endif
6136 } 6149 }
6137 6150
6138 } } // namespace v8::internal 6151 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698