Commit 5a3ea1c8 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Add some comments to the ia32 code generator

Review URL: http://codereview.chromium.org/1918002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4586 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent efe9f30f
...@@ -3333,7 +3333,7 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) { ...@@ -3333,7 +3333,7 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
// Change to slow case in the beginning of an initialization block to // Change to slow case in the beginning of an initialization block to
// avoid the quadratic behavior of repeatedly adding fast properties. // avoid the quadratic behavior of repeatedly adding fast properties.
if (node->starts_initialization_block()) { if (node->starts_initialization_block()) {
// Initialization block consists of assignments on the form expr.x = ..., so // Initialization block consists of assignments of the form expr.x = ..., so
// this will never be an assignment to a variable, so there must be a // this will never be an assignment to a variable, so there must be a
// receiver object. // receiver object.
ASSERT_EQ(NULL, var); ASSERT_EQ(NULL, var);
......
...@@ -5369,10 +5369,13 @@ void CodeGenerator::EmitSlotAssignment(Assignment* node) { ...@@ -5369,10 +5369,13 @@ void CodeGenerator::EmitSlotAssignment(Assignment* node) {
// Evaluate the right-hand side. // Evaluate the right-hand side.
if (node->is_compound()) { if (node->is_compound()) {
// For a compound assignment the right-hand side is a binary operation
// between the current property value and the actual right-hand side.
Result result = LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF); Result result = LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
frame()->Push(&result); frame()->Push(&result);
Load(node->value()); Load(node->value());
// Perform the binary operation.
bool overwrite_value = bool overwrite_value =
(node->value()->AsBinaryOperation() != NULL && (node->value()->AsBinaryOperation() != NULL &&
node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
...@@ -5382,6 +5385,7 @@ void CodeGenerator::EmitSlotAssignment(Assignment* node) { ...@@ -5382,6 +5385,7 @@ void CodeGenerator::EmitSlotAssignment(Assignment* node) {
GenericBinaryOperation(&expr, GenericBinaryOperation(&expr,
overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
} else { } else {
// For non-compound assignment just load the right-hand side.
Load(node->value()); Load(node->value());
} }
...@@ -5404,7 +5408,9 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) { ...@@ -5404,7 +5408,9 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
Property* prop = node->target()->AsProperty(); Property* prop = node->target()->AsProperty();
ASSERT(var == NULL || (prop == NULL && var->is_global())); ASSERT(var == NULL || (prop == NULL && var->is_global()));
// Initialize name and evaluate the receiver subexpression if necessary. // Initialize name and evaluate the receiver sub-expression if necessary. If
// the receiver is trivial it is not placed on the stack at this point, but
// loaded whenever actually needed.
Handle<String> name; Handle<String> name;
bool is_trivial_receiver = false; bool is_trivial_receiver = false;
if (var != NULL) { if (var != NULL) {
...@@ -5418,10 +5424,13 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) { ...@@ -5418,10 +5424,13 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
if (!is_trivial_receiver) Load(prop->obj()); if (!is_trivial_receiver) Load(prop->obj());
} }
// Change to slow case in the beginning of an initialization block to
// avoid the quadratic behavior of repeatedly adding fast properties.
if (node->starts_initialization_block()) { if (node->starts_initialization_block()) {
// Initialization block consists of assignments of the form expr.x = ..., so
// this will never be an assignment to a variable, so there must be a
// receiver object.
ASSERT_EQ(NULL, var); ASSERT_EQ(NULL, var);
// Change to slow case in the beginning of an initialization block to
// avoid the quadratic behavior of repeatedly adding fast properties.
if (is_trivial_receiver) { if (is_trivial_receiver) {
frame()->Push(prop->obj()); frame()->Push(prop->obj());
} else { } else {
...@@ -5430,14 +5439,21 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) { ...@@ -5430,14 +5439,21 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
Result ignored = frame()->CallRuntime(Runtime::kToSlowProperties, 1); Result ignored = frame()->CallRuntime(Runtime::kToSlowProperties, 1);
} }
// Change to fast case at the end of an initialization block. To prepare for
// that add an extra copy of the receiver to the frame, so that it can be
// converted back to fast case after the assignment.
if (node->ends_initialization_block() && !is_trivial_receiver) { if (node->ends_initialization_block() && !is_trivial_receiver) {
// Add an extra copy of the receiver to the frame, so that it can be
// converted back to fast case after the assignment.
frame()->Dup(); frame()->Dup();
} }
// Stack layout:
// [tos] : receiver (only materialized if non-trivial)
// [tos+1] : receiver if at the end of an initialization block
// Evaluate the right-hand side. // Evaluate the right-hand side.
if (node->is_compound()) { if (node->is_compound()) {
// For a compound assignment the right-hand side is a binary operation
// between the current property value and the actual right-hand side.
if (is_trivial_receiver) { if (is_trivial_receiver) {
frame()->Push(prop->obj()); frame()->Push(prop->obj());
} else if (var != NULL) { } else if (var != NULL) {
...@@ -5461,9 +5477,15 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) { ...@@ -5461,9 +5477,15 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
GenericBinaryOperation(&expr, GenericBinaryOperation(&expr,
overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
} else { } else {
// For non-compound assignment just load the right-hand side.
Load(node->value()); Load(node->value());
} }
// Stack layout:
// [tos] : value
// [tos+1] : receiver (only materialized if non-trivial)
// [tos+2] : receiver if at the end of an initialization block
// Perform the assignment. It is safe to ignore constants here. // Perform the assignment. It is safe to ignore constants here.
ASSERT(var == NULL || var->mode() != Variable::CONST); ASSERT(var == NULL || var->mode() != Variable::CONST);
ASSERT_NE(Token::INIT_CONST, node->op()); ASSERT_NE(Token::INIT_CONST, node->op());
...@@ -5477,6 +5499,10 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) { ...@@ -5477,6 +5499,10 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
Result answer = EmitNamedStore(name, is_contextual); Result answer = EmitNamedStore(name, is_contextual);
frame()->Push(&answer); frame()->Push(&answer);
// Stack layout:
// [tos] : result
// [tos+1] : receiver if at the end of an initialization block
if (node->ends_initialization_block()) { if (node->ends_initialization_block()) {
ASSERT_EQ(NULL, var); ASSERT_EQ(NULL, var);
// The argument to the runtime call is the receiver. // The argument to the runtime call is the receiver.
...@@ -5493,6 +5519,9 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) { ...@@ -5493,6 +5519,9 @@ void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1); Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1);
} }
// Stack layout:
// [tos] : result
ASSERT_EQ(frame()->height(), original_height + 1); ASSERT_EQ(frame()->height(), original_height + 1);
} }
...@@ -5501,38 +5530,47 @@ void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) { ...@@ -5501,38 +5530,47 @@ void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) {
#ifdef DEBUG #ifdef DEBUG
int original_height = frame()->height(); int original_height = frame()->height();
#endif #endif
Comment cmnt(masm_, "[ Named Property Assignment"); Comment cmnt(masm_, "[ Keyed Property Assignment");
Property* prop = node->target()->AsProperty(); Property* prop = node->target()->AsProperty();
ASSERT_NOT_NULL(prop); ASSERT_NOT_NULL(prop);
// Evaluate the receiver subexpression. // Evaluate the receiver subexpression.
Load(prop->obj()); Load(prop->obj());
// Change to slow case in the beginning of an initialization block to
// avoid the quadratic behavior of repeatedly adding fast properties.
if (node->starts_initialization_block()) { if (node->starts_initialization_block()) {
// Change to slow case in the beginning of an initialization block to
// avoid the quadratic behavior of repeatedly adding fast properties.
frame_->Dup(); frame_->Dup();
Result ignored = frame_->CallRuntime(Runtime::kToSlowProperties, 1); Result ignored = frame_->CallRuntime(Runtime::kToSlowProperties, 1);
} }
// Change to fast case at the end of an initialization block. To prepare for
// that add an extra copy of the receiver to the frame, so that it can be
// converted back to fast case after the assignment.
if (node->ends_initialization_block()) { if (node->ends_initialization_block()) {
// Add an extra copy of the receiver to the frame, so that it can be
// converted back to fast case after the assignment.
frame_->Dup(); frame_->Dup();
} }
// Evaluate the key subexpression. // Evaluate the key subexpression.
Load(prop->key()); Load(prop->key());
// Stack layout:
// [tos] : key
// [tos+1] : receiver
// [tos+2] : receiver if at the end of an initialization block
// Evaluate the right-hand side. // Evaluate the right-hand side.
if (node->is_compound()) { if (node->is_compound()) {
// Duplicate receiver and key. // For a compound assignment the right-hand side is a binary operation
// between the current property value and the actual right-hand side.
// Duplicate receiver and key for loading the current property value.
frame()->PushElementAt(1); frame()->PushElementAt(1);
frame()->PushElementAt(1); frame()->PushElementAt(1);
Result value = EmitKeyedLoad(); Result value = EmitKeyedLoad();
frame()->Push(&value); frame()->Push(&value);
Load(node->value()); Load(node->value());
// Perform the binary operation.
bool overwrite_value = bool overwrite_value =
(node->value()->AsBinaryOperation() != NULL && (node->value()->AsBinaryOperation() != NULL &&
node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
...@@ -5541,15 +5579,27 @@ void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) { ...@@ -5541,15 +5579,27 @@ void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) {
GenericBinaryOperation(&expr, GenericBinaryOperation(&expr,
overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
} else { } else {
// For non-compound assignment just load the right-hand side.
Load(node->value()); Load(node->value());
} }
// Stack layout:
// [tos] : value
// [tos+1] : key
// [tos+2] : receiver
// [tos+3] : receiver if at the end of an initialization block
// Perform the assignment. It is safe to ignore constants here. // Perform the assignment. It is safe to ignore constants here.
ASSERT(node->op() != Token::INIT_CONST); ASSERT(node->op() != Token::INIT_CONST);
CodeForSourcePosition(node->position()); CodeForSourcePosition(node->position());
Result answer = EmitKeyedStore(prop->key()->type()); Result answer = EmitKeyedStore(prop->key()->type());
frame()->Push(&answer); frame()->Push(&answer);
// Stack layout:
// [tos] : result
// [tos+1] : receiver if at the end of an initialization block
// Change to fast case at the end of an initialization block.
if (node->ends_initialization_block()) { if (node->ends_initialization_block()) {
// The argument to the runtime call is the extra copy of the receiver, // The argument to the runtime call is the extra copy of the receiver,
// which is below the value of the assignment. Swap the receiver and // which is below the value of the assignment. Swap the receiver and
...@@ -5561,6 +5611,9 @@ void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) { ...@@ -5561,6 +5611,9 @@ void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) {
Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1); Result ignored = frame_->CallRuntime(Runtime::kToFastProperties, 1);
} }
// Stack layout:
// [tos] : result
ASSERT(frame()->height() == original_height + 1); ASSERT(frame()->height() == original_height + 1);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment