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

Side by Side Diff: src/interpreter/bytecode-array-builder.cc

Issue 1651133002: [interpreter] Move temporary register allocator into own file. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Incorporate review comments from rmcilroy. Created 4 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/interpreter/bytecode-array-builder.h ('k') | src/interpreter/bytecode-array-iterator.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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/interpreter/bytecode-array-builder.h" 5 #include "src/interpreter/bytecode-array-builder.h"
6 6
7 namespace v8 { 7 namespace v8 {
8 namespace internal { 8 namespace internal {
9 namespace interpreter { 9 namespace interpreter {
10 10
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 GetOperand(operand_index)); 57 GetOperand(operand_index));
58 } 58 }
59 59
60 private: 60 private:
61 const BytecodeArrayBuilder& array_builder_; 61 const BytecodeArrayBuilder& array_builder_;
62 size_t previous_bytecode_start_; 62 size_t previous_bytecode_start_;
63 63
64 DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper); 64 DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper);
65 }; 65 };
66 66
67 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone) 67 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone,
68 int parameter_count,
69 int context_count, int locals_count)
68 : isolate_(isolate), 70 : isolate_(isolate),
69 zone_(zone), 71 zone_(zone),
70 bytecodes_(zone), 72 bytecodes_(zone),
71 bytecode_generated_(false), 73 bytecode_generated_(false),
72 constant_array_builder_(isolate, zone), 74 constant_array_builder_(isolate, zone),
73 handler_table_builder_(isolate, zone), 75 handler_table_builder_(isolate, zone),
74 last_block_end_(0), 76 last_block_end_(0),
75 last_bytecode_start_(~0), 77 last_bytecode_start_(~0),
76 exit_seen_in_block_(false), 78 exit_seen_in_block_(false),
77 unbound_jumps_(0), 79 unbound_jumps_(0),
78 parameter_count_(-1), 80 parameter_count_(parameter_count),
79 local_register_count_(-1), 81 local_register_count_(locals_count),
80 context_register_count_(-1), 82 context_register_count_(context_count),
81 temporary_register_count_(0), 83 temporary_allocator_(zone, fixed_register_count()),
82 free_temporaries_(zone), 84 register_translator_(this) {
83 register_translator_(this) {} 85 DCHECK_GE(parameter_count_, 0);
86 DCHECK_GE(context_register_count_, 0);
87 DCHECK_GE(local_register_count_, 0);
88 }
84 89
85 BytecodeArrayBuilder::~BytecodeArrayBuilder() { DCHECK_EQ(0, unbound_jumps_); } 90 BytecodeArrayBuilder::~BytecodeArrayBuilder() { DCHECK_EQ(0, unbound_jumps_); }
86 91
87
88 void BytecodeArrayBuilder::set_locals_count(int number_of_locals) {
89 local_register_count_ = number_of_locals;
90 DCHECK_LE(context_register_count_, 0);
91 }
92
93
94 void BytecodeArrayBuilder::set_parameter_count(int number_of_parameters) {
95 parameter_count_ = number_of_parameters;
96 }
97
98
99 void BytecodeArrayBuilder::set_context_count(int number_of_contexts) {
100 context_register_count_ = number_of_contexts;
101 DCHECK_GE(local_register_count_, 0);
102 }
103
104
105 Register BytecodeArrayBuilder::first_context_register() const { 92 Register BytecodeArrayBuilder::first_context_register() const {
106 DCHECK_GT(context_register_count_, 0); 93 DCHECK_GT(context_register_count_, 0);
107 return Register(local_register_count_); 94 return Register(local_register_count_);
108 } 95 }
109 96
110 97
111 Register BytecodeArrayBuilder::last_context_register() const { 98 Register BytecodeArrayBuilder::last_context_register() const {
112 DCHECK_GT(context_register_count_, 0); 99 DCHECK_GT(context_register_count_, 0);
113 return Register(local_register_count_ + context_register_count_ - 1); 100 return Register(local_register_count_ + context_register_count_ - 1);
114 } 101 }
115 102
116 103
117 Register BytecodeArrayBuilder::first_temporary_register() const {
118 DCHECK_GT(temporary_register_count_, 0);
119 return Register(fixed_register_count());
120 }
121
122
123 Register BytecodeArrayBuilder::last_temporary_register() const {
124 DCHECK_GT(temporary_register_count_, 0);
125 return Register(fixed_register_count() + temporary_register_count_ - 1);
126 }
127
128
129 Register BytecodeArrayBuilder::Parameter(int parameter_index) const { 104 Register BytecodeArrayBuilder::Parameter(int parameter_index) const {
130 DCHECK_GE(parameter_index, 0); 105 DCHECK_GE(parameter_index, 0);
131 return Register::FromParameterIndex(parameter_index, parameter_count()); 106 return Register::FromParameterIndex(parameter_index, parameter_count());
132 } 107 }
133 108
134 109
135 bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const { 110 bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const {
136 return reg.is_parameter() || reg.index() < locals_count(); 111 return reg.is_parameter() || reg.index() < locals_count();
137 } 112 }
138 113
139 114
140 bool BytecodeArrayBuilder::RegisterIsTemporary(Register reg) const {
141 return temporary_register_count_ > 0 && first_temporary_register() <= reg &&
142 reg <= last_temporary_register();
143 }
144
145
146 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { 115 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
147 DCHECK_EQ(bytecode_generated_, false); 116 DCHECK_EQ(bytecode_generated_, false);
148 EnsureReturn(); 117 EnsureReturn();
149 118
150 int bytecode_size = static_cast<int>(bytecodes_.size()); 119 int bytecode_size = static_cast<int>(bytecodes_.size());
151 int register_count = 120 int register_count =
152 fixed_and_temporary_register_count() + translation_register_count(); 121 fixed_and_temporary_register_count() + translation_register_count();
153 int frame_size = register_count * kPointerSize; 122 int frame_size = register_count * kPointerSize;
154 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray(); 123 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray();
155 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); 124 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable();
(...skipping 1045 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 BytecodeArrayBuilder& BytecodeArrayBuilder::DeleteLookupSlot() { 1170 BytecodeArrayBuilder& BytecodeArrayBuilder::DeleteLookupSlot() {
1202 Output(Bytecode::kDeleteLookupSlot); 1171 Output(Bytecode::kDeleteLookupSlot);
1203 return *this; 1172 return *this;
1204 } 1173 }
1205 1174
1206 1175
1207 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { 1176 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) {
1208 return constant_array_builder()->Insert(object); 1177 return constant_array_builder()->Insert(object);
1209 } 1178 }
1210 1179
1211 void BytecodeArrayBuilder::ForgeTemporaryRegister() { 1180 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const {
1212 temporary_register_count_++; 1181 return temporary_register_allocator()->RegisterIsLive(reg);
1213 } 1182 }
1214 1183
1215 int BytecodeArrayBuilder::BorrowTemporaryRegister() {
1216 if (free_temporaries_.empty()) {
1217 ForgeTemporaryRegister();
1218 return last_temporary_register().index();
1219 } else {
1220 auto pos = free_temporaries_.begin();
1221 int retval = *pos;
1222 free_temporaries_.erase(pos);
1223 return retval;
1224 }
1225 }
1226
1227
1228 int BytecodeArrayBuilder::BorrowTemporaryRegisterNotInRange(int start_index,
1229 int end_index) {
1230 auto index = free_temporaries_.lower_bound(start_index);
1231 if (index == free_temporaries_.begin()) {
1232 // If start_index is the first free register, check for a register
1233 // greater than end_index.
1234 index = free_temporaries_.upper_bound(end_index);
1235 if (index == free_temporaries_.end()) {
1236 ForgeTemporaryRegister();
1237 return last_temporary_register().index();
1238 }
1239 } else {
1240 // If there is a free register < start_index
1241 index--;
1242 }
1243
1244 int retval = *index;
1245 free_temporaries_.erase(index);
1246 return retval;
1247 }
1248
1249
1250 void BytecodeArrayBuilder::BorrowConsecutiveTemporaryRegister(int reg_index) {
1251 DCHECK(free_temporaries_.find(reg_index) != free_temporaries_.end());
1252 free_temporaries_.erase(reg_index);
1253 }
1254
1255
1256 void BytecodeArrayBuilder::ReturnTemporaryRegister(int reg_index) {
1257 DCHECK(free_temporaries_.find(reg_index) == free_temporaries_.end());
1258 free_temporaries_.insert(reg_index);
1259 }
1260
1261
1262 int BytecodeArrayBuilder::PrepareForConsecutiveTemporaryRegisters(
1263 size_t count) {
1264 if (count == 0) {
1265 return -1;
1266 }
1267
1268 // TODO(oth): replace use of set<> here for free_temporaries with a
1269 // more efficient structure. And/or partition into two searches -
1270 // one before the translation window and one after.
1271
1272 // A run will require at least |count| free temporaries.
1273 while (free_temporaries_.size() < count) {
1274 ForgeTemporaryRegister();
1275 free_temporaries_.insert(last_temporary_register().index());
1276 }
1277
1278 // Search within existing temporaries for a run.
1279 auto start = free_temporaries_.begin();
1280 size_t run_length = 0;
1281 for (auto run_end = start; run_end != free_temporaries_.end(); run_end++) {
1282 int expected = *start + static_cast<int>(run_length);
1283 if (*run_end != expected) {
1284 start = run_end;
1285 run_length = 0;
1286 }
1287 Register reg_start(*start);
1288 Register reg_expected(expected);
1289 if (RegisterTranslator::DistanceToTranslationWindow(reg_start) > 0 &&
1290 RegisterTranslator::DistanceToTranslationWindow(reg_expected) <= 0) {
1291 // Run straddles the lower edge of the translation window. Registers
1292 // after the start of this boundary are displaced by the register
1293 // translator to provide a hole for translation. Runs either side
1294 // of the boundary are fine.
1295 start = run_end;
1296 run_length = 0;
1297 }
1298 if (++run_length == count) {
1299 return *start;
1300 }
1301 }
1302
1303 // Continue run if possible across existing last temporary.
1304 if (temporary_register_count_ > 0 &&
1305 (start == free_temporaries_.end() ||
1306 *start + static_cast<int>(run_length) !=
1307 last_temporary_register().index() + 1)) {
1308 run_length = 0;
1309 }
1310
1311 // Pad temporaries if extended run would cross translation boundary.
1312 Register reg_first(*start);
1313 Register reg_last(*start + static_cast<int>(count) - 1);
1314 DCHECK_GT(RegisterTranslator::DistanceToTranslationWindow(reg_first),
1315 RegisterTranslator::DistanceToTranslationWindow(reg_last));
1316 while (RegisterTranslator::DistanceToTranslationWindow(reg_first) > 0 &&
1317 RegisterTranslator::DistanceToTranslationWindow(reg_last) <= 0) {
1318 ForgeTemporaryRegister();
1319 free_temporaries_.insert(last_temporary_register().index());
1320 start = --free_temporaries_.end();
1321 reg_first = Register(*start);
1322 reg_last = Register(*start + static_cast<int>(count) - 1);
1323 run_length = 0;
1324 }
1325
1326 // Ensure enough registers for run.
1327 while (run_length++ < count) {
1328 ForgeTemporaryRegister();
1329 free_temporaries_.insert(last_temporary_register().index());
1330 }
1331
1332 int run_start =
1333 last_temporary_register().index() - static_cast<int>(count) + 1;
1334 DCHECK(RegisterTranslator::DistanceToTranslationWindow(Register(run_start)) <=
1335 0 ||
1336 RegisterTranslator::DistanceToTranslationWindow(
1337 Register(run_start + static_cast<int>(count) - 1)) > 0);
1338 return run_start;
1339 }
1340
1341
1342 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const {
1343 if (temporary_register_count_ > 0) {
1344 DCHECK(reg.index() >= first_temporary_register().index() &&
1345 reg.index() <= last_temporary_register().index());
1346 return free_temporaries_.find(reg.index()) == free_temporaries_.end();
1347 } else {
1348 return false;
1349 }
1350 }
1351
1352
1353 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, 1184 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index,
1354 uint32_t operand_value) const { 1185 uint32_t operand_value) const {
1355 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); 1186 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index);
1356 switch (operand_type) { 1187 switch (operand_type) {
1357 case OperandType::kNone: 1188 case OperandType::kNone:
1358 return false; 1189 return false;
1359 case OperandType::kRegCount16: { 1190 case OperandType::kRegCount16: {
1360 // Expect kRegCount16 is part of a range previous operand is a 1191 // Expect kRegCount16 is part of a range previous operand is a
1361 // valid operand to start a range. 1192 // valid operand to start a range.
1362 if (operand_index > 0) { 1193 if (operand_index > 0) {
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
1813 } 1644 }
1814 1645
1815 // static 1646 // static
1816 bool BytecodeArrayBuilder::FitsInReg16OperandUntranslated(Register value) { 1647 bool BytecodeArrayBuilder::FitsInReg16OperandUntranslated(Register value) {
1817 return value.is_short_operand(); 1648 return value.is_short_operand();
1818 } 1649 }
1819 1650
1820 } // namespace interpreter 1651 } // namespace interpreter
1821 } // namespace internal 1652 } // namespace internal
1822 } // namespace v8 1653 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-array-builder.h ('k') | src/interpreter/bytecode-array-iterator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698