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 3281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3292 expr->GetMonomorphicReceiverType()->has_fast_elements(); | 3292 expr->GetMonomorphicReceiverType()->has_fast_elements(); |
3293 | 3293 |
3294 instr = is_fast_elements | 3294 instr = is_fast_elements |
3295 ? BuildStoreKeyedFastElement(object, key, value, expr) | 3295 ? BuildStoreKeyedFastElement(object, key, value, expr) |
3296 : BuildStoreKeyedGeneric(object, key, value); | 3296 : BuildStoreKeyedGeneric(object, key, value); |
3297 } | 3297 } |
3298 | 3298 |
3299 Push(value); | 3299 Push(value); |
3300 instr->set_position(expr->position()); | 3300 instr->set_position(expr->position()); |
3301 AddInstruction(instr); | 3301 AddInstruction(instr); |
3302 if (instr->HasSideEffects()) AddSimulate(expr->id()); | 3302 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
3303 ast_context()->ReturnValue(Pop()); | 3303 ast_context()->ReturnValue(Pop()); |
3304 } | 3304 } |
3305 | 3305 |
3306 | 3306 |
3307 // Because not every expression has a position and there is not common | 3307 // Because not every expression has a position and there is not common |
3308 // superclass of Assignment and CountOperation, we cannot just pass the | 3308 // superclass of Assignment and CountOperation, we cannot just pass the |
3309 // owning expression instead of position and ast_id separately. | 3309 // owning expression instead of position and ast_id separately. |
3310 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, | 3310 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, |
3311 HValue* value, | 3311 HValue* value, |
3312 int position, | 3312 int position, |
(...skipping 24 matching lines...) Expand all Loading... |
3337 operation->RecordTypeFeedback(oracle()); | 3337 operation->RecordTypeFeedback(oracle()); |
3338 | 3338 |
3339 if (var != NULL) { | 3339 if (var != NULL) { |
3340 if (!var->is_global() && !var->IsStackAllocated()) { | 3340 if (!var->is_global() && !var->IsStackAllocated()) { |
3341 BAILOUT("non-stack/non-global in compound assignment"); | 3341 BAILOUT("non-stack/non-global in compound assignment"); |
3342 } | 3342 } |
3343 | 3343 |
3344 VISIT_FOR_VALUE(operation); | 3344 VISIT_FOR_VALUE(operation); |
3345 | 3345 |
3346 if (var->is_global()) { | 3346 if (var->is_global()) { |
3347 HandleGlobalVariableAssignment(var, Top(), expr->position(), expr->id()); | 3347 HandleGlobalVariableAssignment(var, |
| 3348 Top(), |
| 3349 expr->position(), |
| 3350 expr->AssignmentId()); |
3348 } else { | 3351 } else { |
3349 Bind(var, Top()); | 3352 Bind(var, Top()); |
3350 } | 3353 } |
3351 ast_context()->ReturnValue(Pop()); | 3354 ast_context()->ReturnValue(Pop()); |
3352 | 3355 |
3353 } else if (prop != NULL) { | 3356 } else if (prop != NULL) { |
3354 prop->RecordTypeFeedback(oracle()); | 3357 prop->RecordTypeFeedback(oracle()); |
3355 | 3358 |
3356 if (prop->key()->IsPropertyName()) { | 3359 if (prop->key()->IsPropertyName()) { |
3357 // Named property. | 3360 // Named property. |
3358 VISIT_FOR_VALUE(prop->obj()); | 3361 VISIT_FOR_VALUE(prop->obj()); |
3359 HValue* obj = Top(); | 3362 HValue* obj = Top(); |
3360 | 3363 |
3361 HInstruction* load = NULL; | 3364 HInstruction* load = NULL; |
3362 if (prop->IsMonomorphic()) { | 3365 if (prop->IsMonomorphic()) { |
3363 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 3366 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
3364 Handle<Map> map = prop->GetReceiverTypes()->first(); | 3367 Handle<Map> map = prop->GetReceiverTypes()->first(); |
3365 load = BuildLoadNamed(obj, prop, map, name); | 3368 load = BuildLoadNamed(obj, prop, map, name); |
3366 } else { | 3369 } else { |
3367 load = BuildLoadNamedGeneric(obj, prop); | 3370 load = BuildLoadNamedGeneric(obj, prop); |
3368 } | 3371 } |
3369 PushAndAdd(load); | 3372 PushAndAdd(load); |
3370 if (load->HasSideEffects()) AddSimulate(expr->compound_bailout_id()); | 3373 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); |
3371 | 3374 |
3372 VISIT_FOR_VALUE(expr->value()); | 3375 VISIT_FOR_VALUE(expr->value()); |
3373 HValue* right = Pop(); | 3376 HValue* right = Pop(); |
3374 HValue* left = Pop(); | 3377 HValue* left = Pop(); |
3375 | 3378 |
3376 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 3379 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
3377 PushAndAdd(instr); | 3380 PushAndAdd(instr); |
3378 if (instr->HasSideEffects()) AddSimulate(operation->id()); | 3381 if (instr->HasSideEffects()) AddSimulate(operation->id()); |
3379 | 3382 |
3380 HInstruction* store = BuildStoreNamed(obj, instr, prop); | 3383 HInstruction* store = BuildStoreNamed(obj, instr, prop); |
3381 AddInstruction(store); | 3384 AddInstruction(store); |
3382 if (store->HasSideEffects()) AddSimulate(expr->id()); | |
3383 | |
3384 // Drop the simulated receiver and value. Return the value. | 3385 // Drop the simulated receiver and value. Return the value. |
3385 Drop(2); | 3386 Drop(2); |
3386 ast_context()->ReturnValue(instr); | 3387 Push(instr); |
| 3388 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| 3389 ast_context()->ReturnValue(Pop()); |
3387 | 3390 |
3388 } else { | 3391 } else { |
3389 // Keyed property. | 3392 // Keyed property. |
3390 VISIT_FOR_VALUE(prop->obj()); | 3393 VISIT_FOR_VALUE(prop->obj()); |
3391 VISIT_FOR_VALUE(prop->key()); | 3394 VISIT_FOR_VALUE(prop->key()); |
3392 HValue* obj = environment()->ExpressionStackAt(1); | 3395 HValue* obj = environment()->ExpressionStackAt(1); |
3393 HValue* key = environment()->ExpressionStackAt(0); | 3396 HValue* key = environment()->ExpressionStackAt(0); |
3394 | 3397 |
3395 bool is_fast_elements = prop->IsMonomorphic() && | 3398 bool is_fast_elements = prop->IsMonomorphic() && |
3396 prop->GetMonomorphicReceiverType()->has_fast_elements(); | 3399 prop->GetMonomorphicReceiverType()->has_fast_elements(); |
3397 | 3400 |
3398 HInstruction* load = is_fast_elements | 3401 HInstruction* load = is_fast_elements |
3399 ? BuildLoadKeyedFastElement(obj, key, prop) | 3402 ? BuildLoadKeyedFastElement(obj, key, prop) |
3400 : BuildLoadKeyedGeneric(obj, key); | 3403 : BuildLoadKeyedGeneric(obj, key); |
3401 PushAndAdd(load); | 3404 PushAndAdd(load); |
3402 if (load->HasSideEffects()) AddSimulate(expr->compound_bailout_id()); | 3405 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); |
3403 | 3406 |
3404 VISIT_FOR_VALUE(expr->value()); | 3407 VISIT_FOR_VALUE(expr->value()); |
3405 HValue* right = Pop(); | 3408 HValue* right = Pop(); |
3406 HValue* left = Pop(); | 3409 HValue* left = Pop(); |
3407 | 3410 |
3408 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 3411 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
3409 PushAndAdd(instr); | 3412 PushAndAdd(instr); |
3410 if (instr->HasSideEffects()) AddSimulate(operation->id()); | 3413 if (instr->HasSideEffects()) AddSimulate(operation->id()); |
3411 | 3414 |
3412 HInstruction* store = is_fast_elements | 3415 HInstruction* store = is_fast_elements |
3413 ? BuildStoreKeyedFastElement(obj, key, instr, prop) | 3416 ? BuildStoreKeyedFastElement(obj, key, instr, prop) |
3414 : BuildStoreKeyedGeneric(obj, key, instr); | 3417 : BuildStoreKeyedGeneric(obj, key, instr); |
3415 AddInstruction(store); | 3418 AddInstruction(store); |
3416 if (store->HasSideEffects()) AddSimulate(expr->id()); | |
3417 | |
3418 // Drop the simulated receiver, key, and value. Return the value. | 3419 // Drop the simulated receiver, key, and value. Return the value. |
3419 Drop(3); | 3420 Drop(3); |
3420 ast_context()->ReturnValue(instr); | 3421 Push(instr); |
| 3422 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| 3423 ast_context()->ReturnValue(Pop()); |
3421 } | 3424 } |
3422 | 3425 |
3423 } else { | 3426 } else { |
3424 BAILOUT("invalid lhs in compound assignment"); | 3427 BAILOUT("invalid lhs in compound assignment"); |
3425 } | 3428 } |
3426 } | 3429 } |
3427 | 3430 |
3428 | 3431 |
3429 void HGraphBuilder::VisitAssignment(Assignment* expr) { | 3432 void HGraphBuilder::VisitAssignment(Assignment* expr) { |
3430 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 3433 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
3431 Variable* var = proxy->AsVariable(); | 3434 Variable* var = proxy->AsVariable(); |
3432 Property* prop = expr->target()->AsProperty(); | 3435 Property* prop = expr->target()->AsProperty(); |
3433 ASSERT(var == NULL || prop == NULL); | 3436 ASSERT(var == NULL || prop == NULL); |
3434 | 3437 |
3435 if (expr->is_compound()) { | 3438 if (expr->is_compound()) { |
3436 HandleCompoundAssignment(expr); | 3439 HandleCompoundAssignment(expr); |
3437 return; | 3440 return; |
3438 } | 3441 } |
3439 | 3442 |
3440 if (var != NULL) { | 3443 if (var != NULL) { |
3441 if (proxy->IsArguments()) BAILOUT("assignment to arguments"); | 3444 if (proxy->IsArguments()) BAILOUT("assignment to arguments"); |
3442 | 3445 |
3443 // Handle the assignment. | 3446 // Handle the assignment. |
3444 if (var->is_global()) { | 3447 if (var->is_global()) { |
3445 VISIT_FOR_VALUE(expr->value()); | 3448 VISIT_FOR_VALUE(expr->value()); |
3446 HandleGlobalVariableAssignment(var, Top(), expr->position(), expr->id()); | 3449 HandleGlobalVariableAssignment(var, |
| 3450 Top(), |
| 3451 expr->position(), |
| 3452 expr->AssignmentId()); |
3447 } else { | 3453 } else { |
3448 // We allow reference to the arguments object only in assignemtns | 3454 // We allow reference to the arguments object only in assignemtns |
3449 // to local variables to make sure that the arguments object does | 3455 // to local variables to make sure that the arguments object does |
3450 // not escape and is not modified. | 3456 // not escape and is not modified. |
3451 VariableProxy* rhs = expr->value()->AsVariableProxy(); | 3457 VariableProxy* rhs = expr->value()->AsVariableProxy(); |
3452 if (rhs != NULL && | 3458 if (rhs != NULL && |
3453 rhs->var()->IsStackAllocated() && | 3459 rhs->var()->IsStackAllocated() && |
3454 environment()->Lookup(rhs->var())->CheckFlag(HValue::kIsArguments)) { | 3460 environment()->Lookup(rhs->var())->CheckFlag(HValue::kIsArguments)) { |
3455 Push(environment()->Lookup(rhs->var())); | 3461 Push(environment()->Lookup(rhs->var())); |
3456 } else { | 3462 } else { |
(...skipping 1072 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4529 HInstruction* instr = BuildIncrement(value, inc); | 4535 HInstruction* instr = BuildIncrement(value, inc); |
4530 AddInstruction(instr); | 4536 AddInstruction(instr); |
4531 | 4537 |
4532 if (expr->is_prefix()) { | 4538 if (expr->is_prefix()) { |
4533 Push(instr); | 4539 Push(instr); |
4534 } else { | 4540 } else { |
4535 Push(value); | 4541 Push(value); |
4536 } | 4542 } |
4537 | 4543 |
4538 if (var->is_global()) { | 4544 if (var->is_global()) { |
4539 HandleGlobalVariableAssignment(var, instr, expr->position(), expr->id()); | 4545 HandleGlobalVariableAssignment(var, |
| 4546 instr, |
| 4547 expr->position(), |
| 4548 expr->AssignmentId()); |
4540 } else { | 4549 } else { |
4541 ASSERT(var->IsStackAllocated()); | 4550 ASSERT(var->IsStackAllocated()); |
4542 Bind(var, instr); | 4551 Bind(var, instr); |
4543 } | 4552 } |
4544 ast_context()->ReturnValue(Pop()); | 4553 ast_context()->ReturnValue(Pop()); |
4545 | 4554 |
4546 } else if (prop != NULL) { | 4555 } else if (prop != NULL) { |
4547 prop->RecordTypeFeedback(oracle()); | 4556 prop->RecordTypeFeedback(oracle()); |
4548 | 4557 |
4549 if (prop->key()->IsPropertyName()) { | 4558 if (prop->key()->IsPropertyName()) { |
4550 // Named property. | 4559 // Named property. |
4551 | 4560 |
4552 // Match the full code generator stack by simulating an extra stack | 4561 // Match the full code generator stack by simulating an extra stack |
4553 // element for postfix operations in a value context. | 4562 // element for postfix operations in a value context. |
4554 if (expr->is_postfix() && !ast_context()->IsEffect()) { | 4563 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); |
4555 Push(graph_->GetConstantUndefined()); | 4564 if (has_extra) Push(graph_->GetConstantUndefined()); |
4556 } | |
4557 | 4565 |
4558 VISIT_FOR_VALUE(prop->obj()); | 4566 VISIT_FOR_VALUE(prop->obj()); |
4559 HValue* obj = Top(); | 4567 HValue* obj = Top(); |
4560 | 4568 |
4561 HInstruction* load = NULL; | 4569 HInstruction* load = NULL; |
4562 if (prop->IsMonomorphic()) { | 4570 if (prop->IsMonomorphic()) { |
4563 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 4571 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
4564 Handle<Map> map = prop->GetReceiverTypes()->first(); | 4572 Handle<Map> map = prop->GetReceiverTypes()->first(); |
4565 load = BuildLoadNamed(obj, prop, map, name); | 4573 load = BuildLoadNamed(obj, prop, map, name); |
4566 } else { | 4574 } else { |
4567 load = BuildLoadNamedGeneric(obj, prop); | 4575 load = BuildLoadNamedGeneric(obj, prop); |
4568 } | 4576 } |
4569 PushAndAdd(load); | 4577 PushAndAdd(load); |
4570 if (load->HasSideEffects()) AddSimulate(increment->id()); | 4578 if (load->HasSideEffects()) AddSimulate(increment->id()); |
4571 | 4579 |
4572 HValue* value = Pop(); | 4580 HValue* before = Pop(); |
4573 | |
4574 // There is no deoptimization to after the increment, so we don't need | 4581 // There is no deoptimization to after the increment, so we don't need |
4575 // to simulate the expression stack after this instruction. | 4582 // to simulate the expression stack after this instruction. |
4576 HInstruction* instr = BuildIncrement(value, inc); | 4583 HInstruction* after = BuildIncrement(before, inc); |
4577 AddInstruction(instr); | 4584 AddInstruction(after); |
4578 | 4585 |
4579 HInstruction* store = BuildStoreNamed(obj, instr, prop); | 4586 HInstruction* store = BuildStoreNamed(obj, after, prop); |
4580 AddInstruction(store); | 4587 AddInstruction(store); |
4581 | 4588 |
4582 // Drop simulated receiver and push the result. | 4589 // Overwrite the receiver in the bailout environment with the result |
4583 Drop(1); | 4590 // of the operation, and the placeholder with the original value if |
4584 if (expr->is_prefix()) { | 4591 // necessary. |
4585 Push(instr); | 4592 environment()->SetExpressionStackAt(0, after); |
4586 } else { | 4593 if (has_extra) environment()->SetExpressionStackAt(1, before); |
4587 if (!ast_context()->IsEffect()) Drop(1); // Drop simulated zero. | 4594 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
4588 Push(value); | 4595 Drop(has_extra ? 2 : 1); |
4589 } | |
4590 | 4596 |
4591 if (store->HasSideEffects()) AddSimulate(expr->id()); | 4597 ast_context()->ReturnValue(expr->is_postfix() ? before : after); |
4592 ast_context()->ReturnValue(Pop()); | |
4593 | 4598 |
4594 } else { | 4599 } else { |
4595 // Keyed property. | 4600 // Keyed property. |
4596 | 4601 |
4597 // Match the full code generator stack by simulate an extra stack element | 4602 // Match the full code generator stack by simulate an extra stack element |
4598 // for postfix operations in a value context. | 4603 // for postfix operations in a value context. |
4599 if (expr->is_postfix() && !ast_context()->IsEffect()) { | 4604 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); |
4600 Push(graph_->GetConstantUndefined()); | 4605 if (has_extra) Push(graph_->GetConstantUndefined()); |
4601 } | |
4602 | 4606 |
4603 VISIT_FOR_VALUE(prop->obj()); | 4607 VISIT_FOR_VALUE(prop->obj()); |
4604 VISIT_FOR_VALUE(prop->key()); | 4608 VISIT_FOR_VALUE(prop->key()); |
4605 | |
4606 HValue* obj = environment()->ExpressionStackAt(1); | 4609 HValue* obj = environment()->ExpressionStackAt(1); |
4607 HValue* key = environment()->ExpressionStackAt(0); | 4610 HValue* key = environment()->ExpressionStackAt(0); |
4608 | 4611 |
4609 bool is_fast_elements = prop->IsMonomorphic() && | 4612 bool is_fast_elements = prop->IsMonomorphic() && |
4610 prop->GetMonomorphicReceiverType()->has_fast_elements(); | 4613 prop->GetMonomorphicReceiverType()->has_fast_elements(); |
4611 | 4614 |
4612 HInstruction* load = is_fast_elements | 4615 HInstruction* load = is_fast_elements |
4613 ? BuildLoadKeyedFastElement(obj, key, prop) | 4616 ? BuildLoadKeyedFastElement(obj, key, prop) |
4614 : BuildLoadKeyedGeneric(obj, key); | 4617 : BuildLoadKeyedGeneric(obj, key); |
4615 PushAndAdd(load); | 4618 PushAndAdd(load); |
4616 if (load->HasSideEffects()) AddSimulate(increment->id()); | 4619 if (load->HasSideEffects()) AddSimulate(increment->id()); |
4617 | 4620 |
4618 HValue* value = Pop(); | 4621 HValue* before = Pop(); |
4619 | |
4620 // There is no deoptimization to after the increment, so we don't need | 4622 // There is no deoptimization to after the increment, so we don't need |
4621 // to simulate the expression stack after this instruction. | 4623 // to simulate the expression stack after this instruction. |
4622 HInstruction* instr = BuildIncrement(value, inc); | 4624 HInstruction* after = BuildIncrement(before, inc); |
4623 AddInstruction(instr); | 4625 AddInstruction(after); |
4624 | 4626 |
4625 HInstruction* store = is_fast_elements | 4627 HInstruction* store = is_fast_elements |
4626 ? BuildStoreKeyedFastElement(obj, key, instr, prop) | 4628 ? BuildStoreKeyedFastElement(obj, key, after, prop) |
4627 : new HStoreKeyedGeneric(obj, key, instr); | 4629 : new HStoreKeyedGeneric(obj, key, after); |
4628 AddInstruction(store); | 4630 AddInstruction(store); |
4629 | 4631 |
4630 // Drop simulated receiver and key and push the result. | 4632 // Drop the key from the bailout environment. Overwrite the receiver |
4631 Drop(2); | 4633 // with the result of the operation, and the placeholder with the |
4632 if (expr->is_prefix()) { | 4634 // original value if necessary. |
4633 Push(instr); | 4635 Drop(1); |
4634 } else { | 4636 environment()->SetExpressionStackAt(0, after); |
4635 if (!ast_context()->IsEffect()) Drop(1); // Drop simulated zero. | 4637 if (has_extra) environment()->SetExpressionStackAt(1, before); |
4636 Push(value); | 4638 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
4637 } | 4639 Drop(has_extra ? 2 : 1); |
4638 | 4640 |
4639 if (store->HasSideEffects()) AddSimulate(expr->id()); | 4641 ast_context()->ReturnValue(expr->is_postfix() ? before : after); |
4640 ast_context()->ReturnValue(Pop()); | |
4641 } | 4642 } |
4642 | 4643 |
4643 } else { | 4644 } else { |
4644 BAILOUT("invalid lhs in count operation"); | 4645 BAILOUT("invalid lhs in count operation"); |
4645 } | 4646 } |
4646 } | 4647 } |
4647 | 4648 |
4648 | 4649 |
4649 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, | 4650 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, |
4650 HValue* left, | 4651 HValue* left, |
(...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5665 } | 5666 } |
5666 | 5667 |
5667 #ifdef DEBUG | 5668 #ifdef DEBUG |
5668 if (graph_ != NULL) graph_->Verify(); | 5669 if (graph_ != NULL) graph_->Verify(); |
5669 if (chunk_ != NULL) chunk_->Verify(); | 5670 if (chunk_ != NULL) chunk_->Verify(); |
5670 if (allocator_ != NULL) allocator_->Verify(); | 5671 if (allocator_ != NULL) allocator_->Verify(); |
5671 #endif | 5672 #endif |
5672 } | 5673 } |
5673 | 5674 |
5674 } } // namespace v8::internal | 5675 } } // namespace v8::internal |
OLD | NEW |