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

Side by Side Diff: src/interpreter/bytecode-register-optimizer.cc

Issue 2360193003: Revert of [Interpreter] Optimize BytecodeArrayBuilder and BytecodeArrayWriter. (Closed)
Patch Set: Created 4 years, 2 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-register-optimizer.h ('k') | src/interpreter/bytecode-traits.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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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-register-optimizer.h" 5 #include "src/interpreter/bytecode-register-optimizer.h"
6 6
7 namespace v8 { 7 namespace v8 {
8 namespace internal { 8 namespace internal {
9 namespace interpreter { 9 namespace interpreter {
10 10
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 BytecodeRegisterOptimizer::RegisterInfo* 167 BytecodeRegisterOptimizer::RegisterInfo*
168 BytecodeRegisterOptimizer::RegisterInfo::GetEquivalent() { 168 BytecodeRegisterOptimizer::RegisterInfo::GetEquivalent() {
169 return next_; 169 return next_;
170 } 170 }
171 171
172 BytecodeRegisterOptimizer::BytecodeRegisterOptimizer( 172 BytecodeRegisterOptimizer::BytecodeRegisterOptimizer(
173 Zone* zone, TemporaryRegisterAllocator* register_allocator, 173 Zone* zone, TemporaryRegisterAllocator* register_allocator,
174 int parameter_count, BytecodePipelineStage* next_stage) 174 int parameter_count, BytecodePipelineStage* next_stage)
175 : accumulator_(Register::virtual_accumulator()), 175 : accumulator_(Register::virtual_accumulator()),
176 temporary_base_(register_allocator->allocation_base()), 176 temporary_base_(register_allocator->allocation_base()),
177 max_register_index_(register_allocator->allocation_base() - 1),
178 register_info_table_(zone), 177 register_info_table_(zone),
179 equivalence_id_(0), 178 equivalence_id_(0),
180 next_stage_(next_stage), 179 next_stage_(next_stage),
181 flush_required_(false), 180 flush_required_(false),
182 zone_(zone) { 181 zone_(zone) {
183 register_allocator->set_observer(this); 182 register_allocator->set_observer(this);
184 183
185 // Calculate offset so register index values can be mapped into 184 // Calculate offset so register index values can be mapped into
186 // a vector of register metadata. 185 // a vector of register metadata.
187 if (parameter_count != 0) { 186 if (parameter_count != 0) {
(...skipping 14 matching lines...) Expand all
202 RegisterFromRegisterInfoTableIndex(i), NextEquivalenceId(), true); 201 RegisterFromRegisterInfoTableIndex(i), NextEquivalenceId(), true);
203 DCHECK_EQ(register_info_table_[i]->register_value().index(), 202 DCHECK_EQ(register_info_table_[i]->register_value().index(),
204 RegisterFromRegisterInfoTableIndex(i).index()); 203 RegisterFromRegisterInfoTableIndex(i).index());
205 } 204 }
206 accumulator_info_ = GetRegisterInfo(accumulator_); 205 accumulator_info_ = GetRegisterInfo(accumulator_);
207 DCHECK(accumulator_info_->register_value() == accumulator_); 206 DCHECK(accumulator_info_->register_value() == accumulator_);
208 } 207 }
209 208
210 // override 209 // override
211 Handle<BytecodeArray> BytecodeRegisterOptimizer::ToBytecodeArray( 210 Handle<BytecodeArray> BytecodeRegisterOptimizer::ToBytecodeArray(
212 Isolate* isolate, int register_count, int parameter_count, 211 Isolate* isolate, int fixed_register_count, int parameter_count,
213 Handle<FixedArray> handler_table) { 212 Handle<FixedArray> handler_table) {
214 FlushState(); 213 FlushState();
215 return next_stage_->ToBytecodeArray(isolate, max_register_index_ + 1, 214 return next_stage_->ToBytecodeArray(isolate, fixed_register_count,
216 parameter_count, handler_table); 215 parameter_count, handler_table);
217 } 216 }
218 217
219 // override 218 // override
220 void BytecodeRegisterOptimizer::Write(BytecodeNode* node) { 219 void BytecodeRegisterOptimizer::Write(BytecodeNode* node) {
221 // Jumps are handled by WriteJump.
222 DCHECK(!Bytecodes::IsJump(node->bytecode()));
223 // 220 //
224 // Transfers with observable registers as the destination will be 221 // Transfers with observable registers as the destination will be
225 // immediately materialized so the source position information will 222 // immediately materialized so the source position information will
226 // be ordered correctly. 223 // be ordered correctly.
227 // 224 //
228 // Transfers without observable destination registers will initially 225 // Transfers without observable destination registers will initially
229 // be emitted as Nop's with the source position. They may, or may 226 // be emitted as Nop's with the source position. They may, or may
230 // not, be materialized by the optimizer. However, the source 227 // not, be materialized by the optimizer. However, the source
231 // position is not lost and being attached to a Nop is fine as the 228 // position is not lost and being attached to a Nop is fine as the
232 // destination register is not observable in the debugger. 229 // destination register is not observable in the debugger.
233 // 230 //
234 switch (node->bytecode()) { 231 switch (node->bytecode()) {
235 case Bytecode::kLdar: { 232 case Bytecode::kLdar: {
236 DoLdar(node); 233 DoLdar(node);
237 return; 234 return;
238 } 235 }
239 case Bytecode::kStar: { 236 case Bytecode::kStar: {
240 DoStar(node); 237 DoStar(node);
241 return; 238 return;
242 } 239 }
243 case Bytecode::kMov: { 240 case Bytecode::kMov: {
244 DoMov(node); 241 DoMov(node);
245 return; 242 return;
246 } 243 }
247 default: 244 default:
248 break; 245 break;
249 } 246 }
250 247
251 if (node->bytecode() == Bytecode::kDebugger || 248 if (Bytecodes::IsJump(node->bytecode()) ||
249 node->bytecode() == Bytecode::kDebugger ||
252 node->bytecode() == Bytecode::kSuspendGenerator) { 250 node->bytecode() == Bytecode::kSuspendGenerator) {
253 // All state must be flushed before emitting 251 // All state must be flushed before emitting
252 // - a jump (due to how bytecode offsets for jumps are evaluated),
254 // - a call to the debugger (as it can manipulate locals and parameters), 253 // - a call to the debugger (as it can manipulate locals and parameters),
255 // - a generator suspend (as this involves saving all registers). 254 // - a generator suspend (as this involves saving all registers).
256 FlushState(); 255 FlushState();
257 } 256 }
258 257
259 PrepareOperands(node); 258 PrepareOperands(node);
260 next_stage_->Write(node); 259 WriteToNextStage(node);
261 } 260 }
262 261
263 // override 262 // override
264 void BytecodeRegisterOptimizer::WriteJump(BytecodeNode* node, 263 void BytecodeRegisterOptimizer::WriteJump(BytecodeNode* node,
265 BytecodeLabel* label) { 264 BytecodeLabel* label) {
266 FlushState(); 265 FlushState();
267 next_stage_->WriteJump(node, label); 266 next_stage_->WriteJump(node, label);
268 } 267 }
269 268
270 // override 269 // override
(...skipping 29 matching lines...) Expand all
300 OutputRegisterTransfer(reg_info, equivalent); 299 OutputRegisterTransfer(reg_info, equivalent);
301 } 300 }
302 equivalent->MoveToNewEquivalenceSet(NextEquivalenceId(), true); 301 equivalent->MoveToNewEquivalenceSet(NextEquivalenceId(), true);
303 } 302 }
304 } 303 }
305 } 304 }
306 305
307 flush_required_ = false; 306 flush_required_ = false;
308 } 307 }
309 308
309 void BytecodeRegisterOptimizer::WriteToNextStage(BytecodeNode* node) const {
310 next_stage_->Write(node);
311 }
312
313 void BytecodeRegisterOptimizer::WriteToNextStage(
314 BytecodeNode* node, const BytecodeSourceInfo& source_info) const {
315 if (source_info.is_valid()) {
316 node->source_info().Clone(source_info);
317 }
318 next_stage_->Write(node);
319 }
320
310 void BytecodeRegisterOptimizer::OutputRegisterTransfer( 321 void BytecodeRegisterOptimizer::OutputRegisterTransfer(
311 RegisterInfo* input_info, RegisterInfo* output_info, 322 RegisterInfo* input_info, RegisterInfo* output_info,
312 BytecodeSourceInfo* source_info) { 323 const BytecodeSourceInfo& source_info) {
313 Register input = input_info->register_value(); 324 Register input = input_info->register_value();
314 Register output = output_info->register_value(); 325 Register output = output_info->register_value();
315 DCHECK_NE(input.index(), output.index()); 326 DCHECK_NE(input.index(), output.index());
316 327
317 if (input == accumulator_) { 328 if (input == accumulator_) {
318 uint32_t operand = static_cast<uint32_t>(output.ToOperand()); 329 uint32_t operand = static_cast<uint32_t>(output.ToOperand());
319 BytecodeNode node(Bytecode::kStar, operand, source_info); 330 BytecodeNode node(Bytecode::kStar, operand);
320 next_stage_->Write(&node); 331 WriteToNextStage(&node, source_info);
321 } else if (output == accumulator_) { 332 } else if (output == accumulator_) {
322 uint32_t operand = static_cast<uint32_t>(input.ToOperand()); 333 uint32_t operand = static_cast<uint32_t>(input.ToOperand());
323 BytecodeNode node(Bytecode::kLdar, operand, source_info); 334 BytecodeNode node(Bytecode::kLdar, operand);
324 next_stage_->Write(&node); 335 WriteToNextStage(&node, source_info);
325 } else { 336 } else {
326 uint32_t operand0 = static_cast<uint32_t>(input.ToOperand()); 337 uint32_t operand0 = static_cast<uint32_t>(input.ToOperand());
327 uint32_t operand1 = static_cast<uint32_t>(output.ToOperand()); 338 uint32_t operand1 = static_cast<uint32_t>(output.ToOperand());
328 BytecodeNode node(Bytecode::kMov, operand0, operand1, source_info); 339 BytecodeNode node(Bytecode::kMov, operand0, operand1);
329 next_stage_->Write(&node); 340 WriteToNextStage(&node, source_info);
330 }
331 if (output != accumulator_) {
332 max_register_index_ = std::max(max_register_index_, output.index());
333 } 341 }
334 output_info->set_materialized(true); 342 output_info->set_materialized(true);
335 } 343 }
336 344
337 void BytecodeRegisterOptimizer::CreateMaterializedEquivalent( 345 void BytecodeRegisterOptimizer::CreateMaterializedEquivalent(
338 RegisterInfo* info) { 346 RegisterInfo* info) {
339 DCHECK(info->materialized()); 347 DCHECK(info->materialized());
340 RegisterInfo* unmaterialized = info->GetEquivalentToMaterialize(); 348 RegisterInfo* unmaterialized = info->GetEquivalentToMaterialize();
341 if (unmaterialized) { 349 if (unmaterialized) {
342 OutputRegisterTransfer(info, unmaterialized); 350 OutputRegisterTransfer(info, unmaterialized);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 void BytecodeRegisterOptimizer::AddToEquivalenceSet( 382 void BytecodeRegisterOptimizer::AddToEquivalenceSet(
375 RegisterInfo* set_member, RegisterInfo* non_set_member) { 383 RegisterInfo* set_member, RegisterInfo* non_set_member) {
376 non_set_member->AddToEquivalenceSetOf(set_member); 384 non_set_member->AddToEquivalenceSetOf(set_member);
377 // Flushing is only required when two or more registers are placed 385 // Flushing is only required when two or more registers are placed
378 // in the same equivalence set. 386 // in the same equivalence set.
379 flush_required_ = true; 387 flush_required_ = true;
380 } 388 }
381 389
382 void BytecodeRegisterOptimizer::RegisterTransfer( 390 void BytecodeRegisterOptimizer::RegisterTransfer(
383 RegisterInfo* input_info, RegisterInfo* output_info, 391 RegisterInfo* input_info, RegisterInfo* output_info,
384 BytecodeSourceInfo* source_info) { 392 const BytecodeSourceInfo& source_info) {
385 // Materialize an alternate in the equivalence set that 393 // Materialize an alternate in the equivalence set that
386 // |output_info| is leaving. 394 // |output_info| is leaving.
387 if (output_info->materialized()) { 395 if (output_info->materialized()) {
388 CreateMaterializedEquivalent(output_info); 396 CreateMaterializedEquivalent(output_info);
389 } 397 }
390 398
391 // Add |output_info| to new equivalence set. 399 // Add |output_info| to new equivalence set.
392 if (!output_info->IsInSameEquivalenceSet(input_info)) { 400 if (!output_info->IsInSameEquivalenceSet(input_info)) {
393 AddToEquivalenceSet(input_info, output_info); 401 AddToEquivalenceSet(input_info, output_info);
394 } 402 }
395 403
396 bool output_is_observable = 404 bool output_is_observable =
397 RegisterIsObservable(output_info->register_value()); 405 RegisterIsObservable(output_info->register_value());
398 if (output_is_observable) { 406 if (output_is_observable) {
399 // Force store to be emitted when register is observable. 407 // Force store to be emitted when register is observable.
400 output_info->set_materialized(false); 408 output_info->set_materialized(false);
401 RegisterInfo* materialized_info = input_info->GetMaterializedEquivalent(); 409 RegisterInfo* materialized_info = input_info->GetMaterializedEquivalent();
402 OutputRegisterTransfer(materialized_info, output_info, source_info); 410 OutputRegisterTransfer(materialized_info, output_info, source_info);
403 } else if (source_info->is_valid()) { 411 } else if (source_info.is_valid()) {
404 // Emit a placeholder nop to maintain source position info. 412 // Emit a placeholder nop to maintain source position info.
405 EmitNopForSourceInfo(source_info); 413 EmitNopForSourceInfo(source_info);
406 } 414 }
407 } 415 }
408 416
409 void BytecodeRegisterOptimizer::EmitNopForSourceInfo( 417 void BytecodeRegisterOptimizer::EmitNopForSourceInfo(
410 BytecodeSourceInfo* source_info) const { 418 const BytecodeSourceInfo& source_info) const {
411 DCHECK(source_info->is_valid()); 419 DCHECK(source_info.is_valid());
412 BytecodeNode nop(Bytecode::kNop, source_info); 420 BytecodeNode nop(Bytecode::kNop);
413 next_stage_->Write(&nop); 421 nop.source_info().Clone(source_info);
422 WriteToNextStage(&nop);
414 } 423 }
415 424
416 void BytecodeRegisterOptimizer::DoLdar(BytecodeNode* node) { 425 void BytecodeRegisterOptimizer::DoLdar(const BytecodeNode* const node) {
417 Register input = GetRegisterInputOperand( 426 Register input = GetRegisterInputOperand(
418 0, node->bytecode(), node->operands(), node->operand_count()); 427 0, node->bytecode(), node->operands(), node->operand_count());
419 RegisterInfo* input_info = GetRegisterInfo(input); 428 RegisterInfo* input_info = GetRegisterInfo(input);
420 RegisterTransfer(input_info, accumulator_info_, node->source_info_ptr()); 429 RegisterTransfer(input_info, accumulator_info_, node->source_info());
421 } 430 }
422 431
423 void BytecodeRegisterOptimizer::DoMov(BytecodeNode* node) { 432 void BytecodeRegisterOptimizer::DoMov(const BytecodeNode* const node) {
424 Register input = GetRegisterInputOperand( 433 Register input = GetRegisterInputOperand(
425 0, node->bytecode(), node->operands(), node->operand_count()); 434 0, node->bytecode(), node->operands(), node->operand_count());
426 RegisterInfo* input_info = GetRegisterInfo(input); 435 RegisterInfo* input_info = GetRegisterInfo(input);
427 Register output = GetRegisterOutputOperand( 436 Register output = GetRegisterOutputOperand(
428 1, node->bytecode(), node->operands(), node->operand_count()); 437 1, node->bytecode(), node->operands(), node->operand_count());
429 RegisterInfo* output_info = GetOrCreateRegisterInfo(output); 438 RegisterInfo* output_info = GetOrCreateRegisterInfo(output);
430 RegisterTransfer(input_info, output_info, node->source_info_ptr()); 439 RegisterTransfer(input_info, output_info, node->source_info());
431 } 440 }
432 441
433 void BytecodeRegisterOptimizer::DoStar(BytecodeNode* node) { 442 void BytecodeRegisterOptimizer::DoStar(const BytecodeNode* const node) {
434 Register output = GetRegisterOutputOperand( 443 Register output = GetRegisterOutputOperand(
435 0, node->bytecode(), node->operands(), node->operand_count()); 444 0, node->bytecode(), node->operands(), node->operand_count());
436 RegisterInfo* output_info = GetOrCreateRegisterInfo(output); 445 RegisterInfo* output_info = GetOrCreateRegisterInfo(output);
437 RegisterTransfer(accumulator_info_, output_info, node->source_info_ptr()); 446 RegisterTransfer(accumulator_info_, output_info, node->source_info());
438 } 447 }
439 448
440 void BytecodeRegisterOptimizer::PrepareRegisterOutputOperand( 449 void BytecodeRegisterOptimizer::PrepareRegisterOutputOperand(
441 RegisterInfo* reg_info) { 450 RegisterInfo* reg_info) {
442 if (reg_info->materialized()) { 451 if (reg_info->materialized()) {
443 CreateMaterializedEquivalent(reg_info); 452 CreateMaterializedEquivalent(reg_info);
444 } 453 }
445 max_register_index_ =
446 std::max(max_register_index_, reg_info->register_value().index());
447 reg_info->MoveToNewEquivalenceSet(NextEquivalenceId(), true); 454 reg_info->MoveToNewEquivalenceSet(NextEquivalenceId(), true);
448 } 455 }
449 456
450 void BytecodeRegisterOptimizer::PrepareRegisterRangeOutputOperand( 457 void BytecodeRegisterOptimizer::PrepareRegisterRangeOutputOperand(
451 Register start, int count) { 458 Register start, int count) {
452 for (int i = 0; i < count; ++i) { 459 for (int i = 0; i < count; ++i) {
453 Register reg(start.index() + i); 460 Register reg(start.index() + i);
454 RegisterInfo* reg_info = GetOrCreateRegisterInfo(reg); 461 RegisterInfo* reg_info = GetOrCreateRegisterInfo(reg);
455 PrepareRegisterOutputOperand(reg_info); 462 PrepareRegisterOutputOperand(reg_info);
456 } 463 }
(...skipping 10 matching lines...) Expand all
467 } else { 474 } else {
468 RegisterInfo* equivalent_info = 475 RegisterInfo* equivalent_info =
469 GetMaterializedEquivalentNotAccumulator(reg_info); 476 GetMaterializedEquivalentNotAccumulator(reg_info);
470 return equivalent_info->register_value(); 477 return equivalent_info->register_value();
471 } 478 }
472 } 479 }
473 480
474 void BytecodeRegisterOptimizer::PrepareRegisterInputOperand( 481 void BytecodeRegisterOptimizer::PrepareRegisterInputOperand(
475 BytecodeNode* const node, Register reg, int operand_index) { 482 BytecodeNode* const node, Register reg, int operand_index) {
476 Register equivalent = GetEquivalentRegisterForInputOperand(reg); 483 Register equivalent = GetEquivalentRegisterForInputOperand(reg);
477 node->UpdateOperand(operand_index, 484 node->operands()[operand_index] =
478 static_cast<uint32_t>(equivalent.ToOperand())); 485 static_cast<uint32_t>(equivalent.ToOperand());
479 } 486 }
480 487
481 void BytecodeRegisterOptimizer::PrepareRegisterRangeInputOperand(Register start, 488 void BytecodeRegisterOptimizer::PrepareRegisterRangeInputOperand(Register start,
482 int count) { 489 int count) {
483 for (int i = 0; i < count; ++i) { 490 for (int i = 0; i < count; ++i) {
484 Register current(start.index() + i); 491 Register current(start.index() + i);
485 RegisterInfo* input_info = GetRegisterInfo(current); 492 RegisterInfo* input_info = GetRegisterInfo(current);
486 Materialize(input_info); 493 Materialize(input_info);
487 } 494 }
488 } 495 }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 if (info->materialized()) { 618 if (info->materialized()) {
612 CreateMaterializedEquivalent(info); 619 CreateMaterializedEquivalent(info);
613 } 620 }
614 info->MoveToNewEquivalenceSet(kInvalidEquivalenceId, false); 621 info->MoveToNewEquivalenceSet(kInvalidEquivalenceId, false);
615 } 622 }
616 } 623 }
617 624
618 } // namespace interpreter 625 } // namespace interpreter
619 } // namespace internal 626 } // namespace internal
620 } // namespace v8 627 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-register-optimizer.h ('k') | src/interpreter/bytecode-traits.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698