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

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

Issue 1918002: Add some comments to the ia32 code generator (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 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/arm/codegen-arm.cc ('k') | no next file » | 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 5351 matching lines...) Expand 10 before | Expand all | Expand 10 after
5362 int original_height = frame()->height(); 5362 int original_height = frame()->height();
5363 #endif 5363 #endif
5364 Comment cmnt(masm(), "[ Variable Assignment"); 5364 Comment cmnt(masm(), "[ Variable Assignment");
5365 Variable* var = node->target()->AsVariableProxy()->AsVariable(); 5365 Variable* var = node->target()->AsVariableProxy()->AsVariable();
5366 ASSERT(var != NULL); 5366 ASSERT(var != NULL);
5367 Slot* slot = var->slot(); 5367 Slot* slot = var->slot();
5368 ASSERT(slot != NULL); 5368 ASSERT(slot != NULL);
5369 5369
5370 // Evaluate the right-hand side. 5370 // Evaluate the right-hand side.
5371 if (node->is_compound()) { 5371 if (node->is_compound()) {
5372 // For a compound assignment the right-hand side is a binary operation
5373 // between the current property value and the actual right-hand side.
5372 Result result = LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF); 5374 Result result = LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
5373 frame()->Push(&result); 5375 frame()->Push(&result);
5374 Load(node->value()); 5376 Load(node->value());
5375 5377
5378 // Perform the binary operation.
5376 bool overwrite_value = 5379 bool overwrite_value =
5377 (node->value()->AsBinaryOperation() != NULL && 5380 (node->value()->AsBinaryOperation() != NULL &&
5378 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 5381 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
5379 // Construct the implicit binary operation. 5382 // Construct the implicit binary operation.
5380 BinaryOperation expr(node, node->binary_op(), node->target(), 5383 BinaryOperation expr(node, node->binary_op(), node->target(),
5381 node->value()); 5384 node->value());
5382 GenericBinaryOperation(&expr, 5385 GenericBinaryOperation(&expr,
5383 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); 5386 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
5384 } else { 5387 } else {
5388 // For non-compound assignment just load the right-hand side.
5385 Load(node->value()); 5389 Load(node->value());
5386 } 5390 }
5387 5391
5388 // Perform the assignment. 5392 // Perform the assignment.
5389 if (var->mode() != Variable::CONST || node->op() == Token::INIT_CONST) { 5393 if (var->mode() != Variable::CONST || node->op() == Token::INIT_CONST) {
5390 CodeForSourcePosition(node->position()); 5394 CodeForSourcePosition(node->position());
5391 StoreToSlot(slot, 5395 StoreToSlot(slot,
5392 node->op() == Token::INIT_CONST ? CONST_INIT : NOT_CONST_INIT); 5396 node->op() == Token::INIT_CONST ? CONST_INIT : NOT_CONST_INIT);
5393 } 5397 }
5394 ASSERT(frame()->height() == original_height + 1); 5398 ASSERT(frame()->height() == original_height + 1);
5395 } 5399 }
5396 5400
5397 5401
5398 void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) { 5402 void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
5399 #ifdef DEBUG 5403 #ifdef DEBUG
5400 int original_height = frame()->height(); 5404 int original_height = frame()->height();
5401 #endif 5405 #endif
5402 Comment cmnt(masm(), "[ Named Property Assignment"); 5406 Comment cmnt(masm(), "[ Named Property Assignment");
5403 Variable* var = node->target()->AsVariableProxy()->AsVariable(); 5407 Variable* var = node->target()->AsVariableProxy()->AsVariable();
5404 Property* prop = node->target()->AsProperty(); 5408 Property* prop = node->target()->AsProperty();
5405 ASSERT(var == NULL || (prop == NULL && var->is_global())); 5409 ASSERT(var == NULL || (prop == NULL && var->is_global()));
5406 5410
5407 // Initialize name and evaluate the receiver subexpression if necessary. 5411 // Initialize name and evaluate the receiver sub-expression if necessary. If
5412 // the receiver is trivial it is not placed on the stack at this point, but
5413 // loaded whenever actually needed.
5408 Handle<String> name; 5414 Handle<String> name;
5409 bool is_trivial_receiver = false; 5415 bool is_trivial_receiver = false;
5410 if (var != NULL) { 5416 if (var != NULL) {
5411 name = var->name(); 5417 name = var->name();
5412 } else { 5418 } else {
5413 Literal* lit = prop->key()->AsLiteral(); 5419 Literal* lit = prop->key()->AsLiteral();
5414 ASSERT_NOT_NULL(lit); 5420 ASSERT_NOT_NULL(lit);
5415 name = Handle<String>::cast(lit->handle()); 5421 name = Handle<String>::cast(lit->handle());
5416 // Do not materialize the receiver on the frame if it is trivial. 5422 // Do not materialize the receiver on the frame if it is trivial.
5417 is_trivial_receiver = prop->obj()->IsTrivial(); 5423 is_trivial_receiver = prop->obj()->IsTrivial();
5418 if (!is_trivial_receiver) Load(prop->obj()); 5424 if (!is_trivial_receiver) Load(prop->obj());
5419 } 5425 }
5420 5426
5427 // Change to slow case in the beginning of an initialization block to
5428 // avoid the quadratic behavior of repeatedly adding fast properties.
5421 if (node->starts_initialization_block()) { 5429 if (node->starts_initialization_block()) {
5430 // Initialization block consists of assignments of the form expr.x = ..., so
5431 // this will never be an assignment to a variable, so there must be a
5432 // receiver object.
5422 ASSERT_EQ(NULL, var); 5433 ASSERT_EQ(NULL, var);
5423 // Change to slow case in the beginning of an initialization block to
5424 // avoid the quadratic behavior of repeatedly adding fast properties.
5425 if (is_trivial_receiver) { 5434 if (is_trivial_receiver) {
5426 frame()->Push(prop->obj()); 5435 frame()->Push(prop->obj());
5427 } else { 5436 } else {
5428 frame()->Dup(); 5437 frame()->Dup();
5429 } 5438 }
5430 Result ignored = frame()->CallRuntime(Runtime::kToSlowProperties, 1); 5439 Result ignored = frame()->CallRuntime(Runtime::kToSlowProperties, 1);
5431 } 5440 }
5432 5441
5442 // Change to fast case at the end of an initialization block. To prepare for
5443 // that add an extra copy of the receiver to the frame, so that it can be
5444 // converted back to fast case after the assignment.
5433 if (node->ends_initialization_block() && !is_trivial_receiver) { 5445 if (node->ends_initialization_block() && !is_trivial_receiver) {
5434 // Add an extra copy of the receiver to the frame, so that it can be
5435 // converted back to fast case after the assignment.
5436 frame()->Dup(); 5446 frame()->Dup();
5437 } 5447 }
5438 5448
5449 // Stack layout:
5450 // [tos] : receiver (only materialized if non-trivial)
5451 // [tos+1] : receiver if at the end of an initialization block
5452
5439 // Evaluate the right-hand side. 5453 // Evaluate the right-hand side.
5440 if (node->is_compound()) { 5454 if (node->is_compound()) {
5455 // For a compound assignment the right-hand side is a binary operation
5456 // between the current property value and the actual right-hand side.
5441 if (is_trivial_receiver) { 5457 if (is_trivial_receiver) {
5442 frame()->Push(prop->obj()); 5458 frame()->Push(prop->obj());
5443 } else if (var != NULL) { 5459 } else if (var != NULL) {
5444 // The LoadIC stub expects the object in eax. 5460 // The LoadIC stub expects the object in eax.
5445 // Freeing eax causes the code generator to load the global into it. 5461 // Freeing eax causes the code generator to load the global into it.
5446 frame_->Spill(eax); 5462 frame_->Spill(eax);
5447 LoadGlobal(); 5463 LoadGlobal();
5448 } else { 5464 } else {
5449 frame()->Dup(); 5465 frame()->Dup();
5450 } 5466 }
5451 Result value = EmitNamedLoad(name, var != NULL); 5467 Result value = EmitNamedLoad(name, var != NULL);
5452 frame()->Push(&value); 5468 frame()->Push(&value);
5453 Load(node->value()); 5469 Load(node->value());
5454 5470
5455 bool overwrite_value = 5471 bool overwrite_value =
5456 (node->value()->AsBinaryOperation() != NULL && 5472 (node->value()->AsBinaryOperation() != NULL &&
5457 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 5473 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
5458 // Construct the implicit binary operation. 5474 // Construct the implicit binary operation.
5459 BinaryOperation expr(node, node->binary_op(), node->target(), 5475 BinaryOperation expr(node, node->binary_op(), node->target(),
5460 node->value()); 5476 node->value());
5461 GenericBinaryOperation(&expr, 5477 GenericBinaryOperation(&expr,
5462 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); 5478 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
5463 } else { 5479 } else {
5480 // For non-compound assignment just load the right-hand side.
5464 Load(node->value()); 5481 Load(node->value());
5465 } 5482 }
5466 5483
5484 // Stack layout:
5485 // [tos] : value
5486 // [tos+1] : receiver (only materialized if non-trivial)
5487 // [tos+2] : receiver if at the end of an initialization block
5488
5467 // Perform the assignment. It is safe to ignore constants here. 5489 // Perform the assignment. It is safe to ignore constants here.
5468 ASSERT(var == NULL || var->mode() != Variable::CONST); 5490 ASSERT(var == NULL || var->mode() != Variable::CONST);
5469 ASSERT_NE(Token::INIT_CONST, node->op()); 5491 ASSERT_NE(Token::INIT_CONST, node->op());
5470 if (is_trivial_receiver) { 5492 if (is_trivial_receiver) {
5471 Result value = frame()->Pop(); 5493 Result value = frame()->Pop();
5472 frame()->Push(prop->obj()); 5494 frame()->Push(prop->obj());
5473 frame()->Push(&value); 5495 frame()->Push(&value);
5474 } 5496 }
5475 CodeForSourcePosition(node->position()); 5497 CodeForSourcePosition(node->position());
5476 bool is_contextual = (var != NULL); 5498 bool is_contextual = (var != NULL);
5477 Result answer = EmitNamedStore(name, is_contextual); 5499 Result answer = EmitNamedStore(name, is_contextual);
5478 frame()->Push(&answer); 5500 frame()->Push(&answer);
5479 5501
5502 // Stack layout:
5503 // [tos] : result
5504 // [tos+1] : receiver if at the end of an initialization block
5505
5480 if (node->ends_initialization_block()) { 5506 if (node->ends_initialization_block()) {
5481 ASSERT_EQ(NULL, var); 5507 ASSERT_EQ(NULL, var);
5482 // The argument to the runtime call is the receiver. 5508 // The argument to the runtime call is the receiver.
5483 if (is_trivial_receiver) { 5509 if (is_trivial_receiver) {
5484 frame()->Push(prop->obj()); 5510 frame()->Push(prop->obj());
5485 } else { 5511 } else {
5486 // A copy of the receiver is below the value of the assignment. Swap 5512 // A copy of the receiver is below the value of the assignment. Swap
5487 // the receiver and the value of the assignment expression. 5513 // the receiver and the value of the assignment expression.
5488 Result result = frame()->Pop(); 5514 Result result = frame()->Pop();
5489 Result receiver = frame()->Pop(); 5515 Result receiver = frame()->Pop();
5490 frame()->Push(&result); 5516 frame()->Push(&result);
5491 frame()->Push(&receiver); 5517 frame()->Push(&receiver);
5492 } 5518 }
5493 Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1); 5519 Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1);
5494 } 5520 }
5495 5521
5522 // Stack layout:
5523 // [tos] : result
5524
5496 ASSERT_EQ(frame()->height(), original_height + 1); 5525 ASSERT_EQ(frame()->height(), original_height + 1);
5497 } 5526 }
5498 5527
5499 5528
5500 void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) { 5529 void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) {
5501 #ifdef DEBUG 5530 #ifdef DEBUG
5502 int original_height = frame()->height(); 5531 int original_height = frame()->height();
5503 #endif 5532 #endif
5504 Comment cmnt(masm_, "[ Named Property Assignment"); 5533 Comment cmnt(masm_, "[ Keyed Property Assignment");
5505 Property* prop = node->target()->AsProperty(); 5534 Property* prop = node->target()->AsProperty();
5506 ASSERT_NOT_NULL(prop); 5535 ASSERT_NOT_NULL(prop);
5507 5536
5508 // Evaluate the receiver subexpression. 5537 // Evaluate the receiver subexpression.
5509 Load(prop->obj()); 5538 Load(prop->obj());
5510 5539
5540 // Change to slow case in the beginning of an initialization block to
5541 // avoid the quadratic behavior of repeatedly adding fast properties.
5511 if (node->starts_initialization_block()) { 5542 if (node->starts_initialization_block()) {
5512 // Change to slow case in the beginning of an initialization block to
5513 // avoid the quadratic behavior of repeatedly adding fast properties.
5514 frame_->Dup(); 5543 frame_->Dup();
5515 Result ignored = frame_->CallRuntime(Runtime::kToSlowProperties, 1); 5544 Result ignored = frame_->CallRuntime(Runtime::kToSlowProperties, 1);
5516 } 5545 }
5517 5546
5547 // Change to fast case at the end of an initialization block. To prepare for
5548 // that add an extra copy of the receiver to the frame, so that it can be
5549 // converted back to fast case after the assignment.
5518 if (node->ends_initialization_block()) { 5550 if (node->ends_initialization_block()) {
5519 // Add an extra copy of the receiver to the frame, so that it can be
5520 // converted back to fast case after the assignment.
5521 frame_->Dup(); 5551 frame_->Dup();
5522 } 5552 }
5523 5553
5524 // Evaluate the key subexpression. 5554 // Evaluate the key subexpression.
5525 Load(prop->key()); 5555 Load(prop->key());
5526 5556
5557 // Stack layout:
5558 // [tos] : key
5559 // [tos+1] : receiver
5560 // [tos+2] : receiver if at the end of an initialization block
5561
5527 // Evaluate the right-hand side. 5562 // Evaluate the right-hand side.
5528 if (node->is_compound()) { 5563 if (node->is_compound()) {
5529 // Duplicate receiver and key. 5564 // For a compound assignment the right-hand side is a binary operation
5565 // between the current property value and the actual right-hand side.
5566 // Duplicate receiver and key for loading the current property value.
5530 frame()->PushElementAt(1); 5567 frame()->PushElementAt(1);
5531 frame()->PushElementAt(1); 5568 frame()->PushElementAt(1);
5532 Result value = EmitKeyedLoad(); 5569 Result value = EmitKeyedLoad();
5533 frame()->Push(&value); 5570 frame()->Push(&value);
5534 Load(node->value()); 5571 Load(node->value());
5535 5572
5573 // Perform the binary operation.
5536 bool overwrite_value = 5574 bool overwrite_value =
5537 (node->value()->AsBinaryOperation() != NULL && 5575 (node->value()->AsBinaryOperation() != NULL &&
5538 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 5576 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
5539 BinaryOperation expr(node, node->binary_op(), node->target(), 5577 BinaryOperation expr(node, node->binary_op(), node->target(),
5540 node->value()); 5578 node->value());
5541 GenericBinaryOperation(&expr, 5579 GenericBinaryOperation(&expr,
5542 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); 5580 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
5543 } else { 5581 } else {
5582 // For non-compound assignment just load the right-hand side.
5544 Load(node->value()); 5583 Load(node->value());
5545 } 5584 }
5546 5585
5586 // Stack layout:
5587 // [tos] : value
5588 // [tos+1] : key
5589 // [tos+2] : receiver
5590 // [tos+3] : receiver if at the end of an initialization block
5591
5547 // Perform the assignment. It is safe to ignore constants here. 5592 // Perform the assignment. It is safe to ignore constants here.
5548 ASSERT(node->op() != Token::INIT_CONST); 5593 ASSERT(node->op() != Token::INIT_CONST);
5549 CodeForSourcePosition(node->position()); 5594 CodeForSourcePosition(node->position());
5550 Result answer = EmitKeyedStore(prop->key()->type()); 5595 Result answer = EmitKeyedStore(prop->key()->type());
5551 frame()->Push(&answer); 5596 frame()->Push(&answer);
5552 5597
5598 // Stack layout:
5599 // [tos] : result
5600 // [tos+1] : receiver if at the end of an initialization block
5601
5602 // Change to fast case at the end of an initialization block.
5553 if (node->ends_initialization_block()) { 5603 if (node->ends_initialization_block()) {
5554 // The argument to the runtime call is the extra copy of the receiver, 5604 // The argument to the runtime call is the extra copy of the receiver,
5555 // which is below the value of the assignment. Swap the receiver and 5605 // which is below the value of the assignment. Swap the receiver and
5556 // the value of the assignment expression. 5606 // the value of the assignment expression.
5557 Result result = frame()->Pop(); 5607 Result result = frame()->Pop();
5558 Result receiver = frame()->Pop(); 5608 Result receiver = frame()->Pop();
5559 frame()->Push(&result); 5609 frame()->Push(&result);
5560 frame()->Push(&receiver); 5610 frame()->Push(&receiver);
5561 Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1); 5611 Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1);
5562 } 5612 }
5563 5613
5614 // Stack layout:
5615 // [tos] : result
5616
5564 ASSERT(frame()->height() == original_height + 1); 5617 ASSERT(frame()->height() == original_height + 1);
5565 } 5618 }
5566 5619
5567 5620
5568 void CodeGenerator::VisitAssignment(Assignment* node) { 5621 void CodeGenerator::VisitAssignment(Assignment* node) {
5569 ASSERT(!in_safe_int32_mode()); 5622 ASSERT(!in_safe_int32_mode());
5570 #ifdef DEBUG 5623 #ifdef DEBUG
5571 int original_height = frame()->height(); 5624 int original_height = frame()->height();
5572 #endif 5625 #endif
5573 Variable* var = node->target()->AsVariableProxy()->AsVariable(); 5626 Variable* var = node->target()->AsVariableProxy()->AsVariable();
(...skipping 7490 matching lines...) Expand 10 before | Expand all | Expand 10 after
13064 13117
13065 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 13118 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
13066 // tagged as a small integer. 13119 // tagged as a small integer.
13067 __ bind(&runtime); 13120 __ bind(&runtime);
13068 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 13121 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
13069 } 13122 }
13070 13123
13071 #undef __ 13124 #undef __
13072 13125
13073 } } // namespace v8::internal 13126 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698