| 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 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 LInstruction* LChunkBuilder::DefineAsRegister(LInstruction* instr) { | 760 LInstruction* LChunkBuilder::DefineAsRegister(LInstruction* instr) { |
| 761 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); | 761 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); |
| 762 } | 762 } |
| 763 | 763 |
| 764 | 764 |
| 765 LInstruction* LChunkBuilder::DefineAsSpilled(LInstruction* instr, int index) { | 765 LInstruction* LChunkBuilder::DefineAsSpilled(LInstruction* instr, int index) { |
| 766 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index)); | 766 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index)); |
| 767 } | 767 } |
| 768 | 768 |
| 769 | 769 |
| 770 LInstruction* LChunkBuilder::DefineSameAsAny(LInstruction* instr) { | |
| 771 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_ANY_INPUT)); | |
| 772 } | |
| 773 | |
| 774 | |
| 775 LInstruction* LChunkBuilder::DefineSameAsFirst(LInstruction* instr) { | 770 LInstruction* LChunkBuilder::DefineSameAsFirst(LInstruction* instr) { |
| 776 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT)); | 771 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT)); |
| 777 } | 772 } |
| 778 | 773 |
| 779 | 774 |
| 780 LInstruction* LChunkBuilder::DefineFixed(LInstruction* instr, Register reg) { | 775 LInstruction* LChunkBuilder::DefineFixed(LInstruction* instr, Register reg) { |
| 781 return Define(instr, ToUnallocated(reg)); | 776 return Define(instr, ToUnallocated(reg)); |
| 782 } | 777 } |
| 783 | 778 |
| 784 | 779 |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 last_environment->SetValueAt(block->deleted_phis()->at(i), | 1004 last_environment->SetValueAt(block->deleted_phis()->at(i), |
| 1010 graph_->GetConstantUndefined()); | 1005 graph_->GetConstantUndefined()); |
| 1011 } | 1006 } |
| 1012 block->UpdateEnvironment(last_environment); | 1007 block->UpdateEnvironment(last_environment); |
| 1013 // Pick up the outgoing argument count of one of the predecessors. | 1008 // Pick up the outgoing argument count of one of the predecessors. |
| 1014 argument_count_ = pred->argument_count(); | 1009 argument_count_ = pred->argument_count(); |
| 1015 } | 1010 } |
| 1016 HInstruction* current = block->first(); | 1011 HInstruction* current = block->first(); |
| 1017 int start = chunk_->instructions()->length(); | 1012 int start = chunk_->instructions()->length(); |
| 1018 while (current != NULL && !is_aborted()) { | 1013 while (current != NULL && !is_aborted()) { |
| 1019 if (FLAG_trace_environment) { | |
| 1020 PrintF("Process instruction %d\n", current->id()); | |
| 1021 } | |
| 1022 // Code for constants in registers is generated lazily. | 1014 // Code for constants in registers is generated lazily. |
| 1023 if (!current->EmitAtUses()) { | 1015 if (!current->EmitAtUses()) { |
| 1024 VisitInstruction(current); | 1016 VisitInstruction(current); |
| 1025 } | 1017 } |
| 1026 current = current->next(); | 1018 current = current->next(); |
| 1027 } | 1019 } |
| 1028 int end = chunk_->instructions()->length() - 1; | 1020 int end = chunk_->instructions()->length() - 1; |
| 1029 if (end >= start) { | 1021 if (end >= start) { |
| 1030 block->set_first_instruction_index(start); | 1022 block->set_first_instruction_index(start); |
| 1031 block->set_last_instruction_index(end); | 1023 block->set_last_instruction_index(end); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1118 stream->Add("]"); | 1110 stream->Add("]"); |
| 1119 } | 1111 } |
| 1120 | 1112 |
| 1121 | 1113 |
| 1122 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { | 1114 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { |
| 1123 if (hydrogen_env == NULL) return NULL; | 1115 if (hydrogen_env == NULL) return NULL; |
| 1124 | 1116 |
| 1125 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); | 1117 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); |
| 1126 int ast_id = hydrogen_env->ast_id(); | 1118 int ast_id = hydrogen_env->ast_id(); |
| 1127 ASSERT(ast_id != AstNode::kNoNumber); | 1119 ASSERT(ast_id != AstNode::kNoNumber); |
| 1128 int value_count = hydrogen_env->values()->length(); | 1120 int value_count = hydrogen_env->length(); |
| 1129 LEnvironment* result = new LEnvironment(hydrogen_env->closure(), | 1121 LEnvironment* result = new LEnvironment(hydrogen_env->closure(), |
| 1130 ast_id, | 1122 ast_id, |
| 1131 hydrogen_env->parameter_count(), | 1123 hydrogen_env->parameter_count(), |
| 1132 argument_count_, | 1124 argument_count_, |
| 1133 value_count, | 1125 value_count, |
| 1134 outer); | 1126 outer); |
| 1135 int argument_index = 0; | 1127 int argument_index = 0; |
| 1136 for (int i = 0; i < value_count; ++i) { | 1128 for (int i = 0; i < value_count; ++i) { |
| 1137 HValue* value = hydrogen_env->values()->at(i); | 1129 HValue* value = hydrogen_env->values()->at(i); |
| 1138 LOperand* op = NULL; | 1130 LOperand* op = NULL; |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1670 | 1662 |
| 1671 | 1663 |
| 1672 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { | 1664 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { |
| 1673 ASSERT(instr->value()->representation().IsTagged()); | 1665 ASSERT(instr->value()->representation().IsTagged()); |
| 1674 LOperand* value = UseTempRegister(instr->value()); | 1666 LOperand* value = UseTempRegister(instr->value()); |
| 1675 | 1667 |
| 1676 return DefineSameAsFirst(new LClassOfTest(value, TempRegister())); | 1668 return DefineSameAsFirst(new LClassOfTest(value, TempRegister())); |
| 1677 } | 1669 } |
| 1678 | 1670 |
| 1679 | 1671 |
| 1680 LInstruction* LChunkBuilder::DoArrayLength(HArrayLength* instr) { | 1672 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { |
| 1681 LOperand* array = NULL; | 1673 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1682 LOperand* temporary = NULL; | 1674 return DefineAsRegister(new LJSArrayLength(array)); |
| 1683 | |
| 1684 if (instr->value()->IsLoadElements()) { | |
| 1685 array = UseRegisterAtStart(instr->value()); | |
| 1686 } else { | |
| 1687 array = UseRegister(instr->value()); | |
| 1688 temporary = TempRegister(); | |
| 1689 } | |
| 1690 | |
| 1691 LInstruction* result = new LArrayLength(array, temporary); | |
| 1692 return AssignEnvironment(DefineAsRegister(result)); | |
| 1693 } | 1675 } |
| 1694 | 1676 |
| 1695 | 1677 |
| 1678 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { |
| 1679 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1680 return DefineAsRegister(new LFixedArrayLength(array)); |
| 1681 } |
| 1682 |
| 1683 |
| 1696 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { | 1684 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { |
| 1697 LOperand* object = UseRegister(instr->value()); | 1685 LOperand* object = UseRegister(instr->value()); |
| 1698 LInstruction* result = new LValueOf(object, TempRegister()); | 1686 LInstruction* result = new LValueOf(object, TempRegister()); |
| 1699 return AssignEnvironment(DefineSameAsFirst(result)); | 1687 return AssignEnvironment(DefineSameAsFirst(result)); |
| 1700 } | 1688 } |
| 1701 | 1689 |
| 1702 | 1690 |
| 1703 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { | 1691 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { |
| 1704 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), | 1692 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), |
| 1705 Use(instr->length()))); | 1693 Use(instr->length()))); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1853 } | 1841 } |
| 1854 | 1842 |
| 1855 | 1843 |
| 1856 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { | 1844 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
| 1857 LOperand* object = UseFixed(instr->object(), eax); | 1845 LOperand* object = UseFixed(instr->object(), eax); |
| 1858 LInstruction* result = DefineFixed(new LLoadNamedGeneric(object), eax); | 1846 LInstruction* result = DefineFixed(new LLoadNamedGeneric(object), eax); |
| 1859 return MarkAsCall(result, instr); | 1847 return MarkAsCall(result, instr); |
| 1860 } | 1848 } |
| 1861 | 1849 |
| 1862 | 1850 |
| 1851 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( |
| 1852 HLoadFunctionPrototype* instr) { |
| 1853 return AssignEnvironment(DefineAsRegister( |
| 1854 new LLoadFunctionPrototype(UseRegister(instr->function()), |
| 1855 TempRegister()))); |
| 1856 } |
| 1857 |
| 1858 |
| 1863 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { | 1859 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { |
| 1864 LOperand* input = UseRegisterAtStart(instr->value()); | 1860 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1865 return DefineSameAsFirst(new LLoadElements(input)); | 1861 return DefineSameAsFirst(new LLoadElements(input)); |
| 1866 } | 1862 } |
| 1867 | 1863 |
| 1868 | 1864 |
| 1869 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( | 1865 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( |
| 1870 HLoadKeyedFastElement* instr) { | 1866 HLoadKeyedFastElement* instr) { |
| 1871 Representation r = instr->representation(); | 1867 Representation r = instr->representation(); |
| 1872 LOperand* obj = UseRegisterAtStart(instr->object()); | 1868 LOperand* obj = UseRegisterAtStart(instr->object()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1924 | 1920 |
| 1925 ASSERT(instr->object()->representation().IsTagged()); | 1921 ASSERT(instr->object()->representation().IsTagged()); |
| 1926 ASSERT(instr->key()->representation().IsTagged()); | 1922 ASSERT(instr->key()->representation().IsTagged()); |
| 1927 ASSERT(instr->value()->representation().IsTagged()); | 1923 ASSERT(instr->value()->representation().IsTagged()); |
| 1928 | 1924 |
| 1929 return MarkAsCall(new LStoreKeyedGeneric(obj, key, val), instr); | 1925 return MarkAsCall(new LStoreKeyedGeneric(obj, key, val), instr); |
| 1930 } | 1926 } |
| 1931 | 1927 |
| 1932 | 1928 |
| 1933 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { | 1929 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { |
| 1934 bool needs_write_barrier = !instr->value()->type().IsSmi(); | 1930 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 1935 | 1931 |
| 1936 LOperand* obj = needs_write_barrier | 1932 LOperand* obj = needs_write_barrier |
| 1937 ? UseTempRegister(instr->object()) | 1933 ? UseTempRegister(instr->object()) |
| 1938 : UseRegisterAtStart(instr->object()); | 1934 : UseRegisterAtStart(instr->object()); |
| 1939 | 1935 |
| 1940 LOperand* val = needs_write_barrier | 1936 LOperand* val = needs_write_barrier |
| 1941 ? UseTempRegister(instr->value()) | 1937 ? UseTempRegister(instr->value()) |
| 1942 : UseRegister(instr->value()); | 1938 : UseRegister(instr->value()); |
| 1943 | 1939 |
| 1944 // We only need a scratch register if we have a write barrier or we | 1940 // We only need a scratch register if we have a write barrier or we |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2028 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { | 2024 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { |
| 2029 LOperand* arguments = UseRegister(instr->arguments()); | 2025 LOperand* arguments = UseRegister(instr->arguments()); |
| 2030 LOperand* length = UseTempRegister(instr->length()); | 2026 LOperand* length = UseTempRegister(instr->length()); |
| 2031 LOperand* index = Use(instr->index()); | 2027 LOperand* index = Use(instr->index()); |
| 2032 LInstruction* result = new LAccessArgumentsAt(arguments, length, index); | 2028 LInstruction* result = new LAccessArgumentsAt(arguments, length, index); |
| 2033 return DefineAsRegister(AssignEnvironment(result)); | 2029 return DefineAsRegister(AssignEnvironment(result)); |
| 2034 } | 2030 } |
| 2035 | 2031 |
| 2036 | 2032 |
| 2037 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 2033 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
| 2038 LInstruction* result = new LTypeof(Use(instr->value())); | 2034 LInstruction* result = new LTypeof(UseAtStart(instr->value())); |
| 2039 return MarkAsCall(DefineFixed(result, eax), instr); | 2035 return MarkAsCall(DefineFixed(result, eax), instr); |
| 2040 } | 2036 } |
| 2041 | 2037 |
| 2042 | 2038 |
| 2043 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { | 2039 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { |
| 2044 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); | 2040 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); |
| 2045 } | 2041 } |
| 2046 | 2042 |
| 2047 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 2043 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
| 2048 HEnvironment* env = current_block_->last_environment(); | 2044 HEnvironment* env = current_block_->last_environment(); |
| 2049 ASSERT(env != NULL); | 2045 ASSERT(env != NULL); |
| 2050 | 2046 |
| 2051 env->set_ast_id(instr->ast_id()); | 2047 env->set_ast_id(instr->ast_id()); |
| 2052 | 2048 |
| 2053 env->Drop(instr->pop_count()); | 2049 env->Drop(instr->pop_count()); |
| 2054 for (int i = 0; i < instr->values()->length(); ++i) { | 2050 for (int i = 0; i < instr->values()->length(); ++i) { |
| 2055 HValue* value = instr->values()->at(i); | 2051 HValue* value = instr->values()->at(i); |
| 2056 if (instr->HasAssignedIndexAt(i)) { | 2052 if (instr->HasAssignedIndexAt(i)) { |
| 2057 env->Bind(instr->GetAssignedIndexAt(i), value); | 2053 env->Bind(instr->GetAssignedIndexAt(i), value); |
| 2058 } else { | 2054 } else { |
| 2059 env->Push(value); | 2055 env->Push(value); |
| 2060 } | 2056 } |
| 2061 } | 2057 } |
| 2062 | 2058 ASSERT(env->length() == instr->environment_length()); |
| 2063 if (FLAG_trace_environment) { | |
| 2064 PrintF("Reconstructed environment ast_id=%d, instr_id=%d\n", | |
| 2065 instr->ast_id(), | |
| 2066 instr->id()); | |
| 2067 env->PrintToStd(); | |
| 2068 } | |
| 2069 ASSERT(env->values()->length() == instr->environment_height()); | |
| 2070 | 2059 |
| 2071 // If there is an instruction pending deoptimization environment create a | 2060 // If there is an instruction pending deoptimization environment create a |
| 2072 // lazy bailout instruction to capture the environment. | 2061 // lazy bailout instruction to capture the environment. |
| 2073 if (pending_deoptimization_ast_id_ == instr->ast_id()) { | 2062 if (pending_deoptimization_ast_id_ == instr->ast_id()) { |
| 2074 LInstruction* result = new LLazyBailout; | 2063 LInstruction* result = new LLazyBailout; |
| 2075 result = AssignEnvironment(result); | 2064 result = AssignEnvironment(result); |
| 2076 instructions_pending_deoptimization_environment_-> | 2065 instructions_pending_deoptimization_environment_-> |
| 2077 set_deoptimization_environment(result->environment()); | 2066 set_deoptimization_environment(result->environment()); |
| 2078 ClearInstructionPendingDeoptimizationEnvironment(); | 2067 ClearInstructionPendingDeoptimizationEnvironment(); |
| 2079 return result; | 2068 return result; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2119 void LPointerMap::PrintTo(StringStream* stream) const { | 2108 void LPointerMap::PrintTo(StringStream* stream) const { |
| 2120 stream->Add("{"); | 2109 stream->Add("{"); |
| 2121 for (int i = 0; i < pointer_operands_.length(); ++i) { | 2110 for (int i = 0; i < pointer_operands_.length(); ++i) { |
| 2122 if (i != 0) stream->Add(";"); | 2111 if (i != 0) stream->Add(";"); |
| 2123 pointer_operands_[i]->PrintTo(stream); | 2112 pointer_operands_[i]->PrintTo(stream); |
| 2124 } | 2113 } |
| 2125 stream->Add("} @%d", position()); | 2114 stream->Add("} @%d", position()); |
| 2126 } | 2115 } |
| 2127 | 2116 |
| 2128 } } // namespace v8::internal | 2117 } } // namespace v8::internal |
| OLD | NEW |