Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 3196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3207 instr = BuildStoreNamedGeneric(object, name, value); | 3207 instr = BuildStoreNamedGeneric(object, name, value); |
| 3208 } | 3208 } |
| 3209 | 3209 |
| 3210 } else { | 3210 } else { |
| 3211 // Keyed store. | 3211 // Keyed store. |
| 3212 VISIT_FOR_VALUE(prop->key()); | 3212 VISIT_FOR_VALUE(prop->key()); |
| 3213 VISIT_FOR_VALUE(expr->value()); | 3213 VISIT_FOR_VALUE(expr->value()); |
| 3214 value = Pop(); | 3214 value = Pop(); |
| 3215 HValue* key = Pop(); | 3215 HValue* key = Pop(); |
| 3216 HValue* object = Pop(); | 3216 HValue* object = Pop(); |
| 3217 | 3217 instr = BuildStoreKeyed(object, |
|
Mads Ager (chromium)
2011/04/06 16:45:15
Looks like this will not fit on one line?
| |
| 3218 if (expr->IsMonomorphic()) { | 3218 key, |
| 3219 Handle<Map> receiver_type(expr->GetMonomorphicReceiverType()); | 3219 value, |
| 3220 // An object has either fast elements or external array elements, but | 3220 expr); |
| 3221 // never both. Pixel array maps that are assigned to pixel array elements | |
| 3222 // are always created with the fast elements flag cleared. | |
| 3223 if (receiver_type->has_external_array_elements()) { | |
| 3224 instr = BuildStoreKeyedSpecializedArrayElement(object, | |
| 3225 key, | |
| 3226 value, | |
| 3227 expr); | |
| 3228 } else if (receiver_type->has_fast_elements()) { | |
| 3229 instr = BuildStoreKeyedFastElement(object, key, value, expr); | |
| 3230 } | |
| 3231 } | |
| 3232 if (instr == NULL) { | |
| 3233 instr = BuildStoreKeyedGeneric(object, key, value); | |
| 3234 } | |
| 3235 } | 3221 } |
| 3236 | |
| 3237 Push(value); | 3222 Push(value); |
| 3238 instr->set_position(expr->position()); | 3223 instr->set_position(expr->position()); |
| 3239 AddInstruction(instr); | 3224 AddInstruction(instr); |
| 3240 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3225 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| 3241 ast_context()->ReturnValue(Pop()); | 3226 ast_context()->ReturnValue(Pop()); |
| 3242 } | 3227 } |
| 3243 | 3228 |
| 3244 | 3229 |
| 3245 // Because not every expression has a position and there is not common | 3230 // Because not every expression has a position and there is not common |
| 3246 // superclass of Assignment and CountOperation, we cannot just pass the | 3231 // superclass of Assignment and CountOperation, we cannot just pass the |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3290 HStoreContextSlot* instr = new HStoreContextSlot(context, index, Top()); | 3275 HStoreContextSlot* instr = new HStoreContextSlot(context, index, Top()); |
| 3291 AddInstruction(instr); | 3276 AddInstruction(instr); |
| 3292 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3277 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| 3293 } else { | 3278 } else { |
| 3294 BAILOUT("compound assignment to lookup slot"); | 3279 BAILOUT("compound assignment to lookup slot"); |
| 3295 } | 3280 } |
| 3296 ast_context()->ReturnValue(Pop()); | 3281 ast_context()->ReturnValue(Pop()); |
| 3297 | 3282 |
| 3298 } else if (prop != NULL) { | 3283 } else if (prop != NULL) { |
| 3299 prop->RecordTypeFeedback(oracle()); | 3284 prop->RecordTypeFeedback(oracle()); |
| 3285 expr->RecordTypeFeedback(oracle()); | |
|
Mads Ager (chromium)
2011/04/06 16:45:15
Maybe move this to the only branch where it is nee
| |
| 3300 | 3286 |
| 3301 if (prop->key()->IsPropertyName()) { | 3287 if (prop->key()->IsPropertyName()) { |
| 3302 // Named property. | 3288 // Named property. |
| 3303 VISIT_FOR_VALUE(prop->obj()); | 3289 VISIT_FOR_VALUE(prop->obj()); |
| 3304 HValue* obj = Top(); | 3290 HValue* obj = Top(); |
| 3305 | 3291 |
| 3306 HInstruction* load = NULL; | 3292 HInstruction* load = NULL; |
| 3307 if (prop->IsMonomorphic()) { | 3293 if (prop->IsMonomorphic()) { |
| 3308 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 3294 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 3309 Handle<Map> map = prop->GetReceiverTypes()->first(); | 3295 Handle<Map> map = prop->GetReceiverTypes()->first(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 3330 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3316 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| 3331 ast_context()->ReturnValue(Pop()); | 3317 ast_context()->ReturnValue(Pop()); |
| 3332 | 3318 |
| 3333 } else { | 3319 } else { |
| 3334 // Keyed property. | 3320 // Keyed property. |
| 3335 VISIT_FOR_VALUE(prop->obj()); | 3321 VISIT_FOR_VALUE(prop->obj()); |
| 3336 VISIT_FOR_VALUE(prop->key()); | 3322 VISIT_FOR_VALUE(prop->key()); |
| 3337 HValue* obj = environment()->ExpressionStackAt(1); | 3323 HValue* obj = environment()->ExpressionStackAt(1); |
| 3338 HValue* key = environment()->ExpressionStackAt(0); | 3324 HValue* key = environment()->ExpressionStackAt(0); |
| 3339 | 3325 |
| 3340 bool is_fast_elements = prop->IsMonomorphic() && | 3326 HInstruction* load = BuildLoadKeyed(obj, key, prop); |
| 3341 prop->GetMonomorphicReceiverType()->has_fast_elements(); | |
| 3342 HInstruction* load = is_fast_elements | |
| 3343 ? BuildLoadKeyedFastElement(obj, key, prop) | |
| 3344 : BuildLoadKeyedGeneric(obj, key); | |
| 3345 PushAndAdd(load); | 3327 PushAndAdd(load); |
| 3346 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); | 3328 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); |
| 3347 | 3329 |
| 3348 VISIT_FOR_VALUE(expr->value()); | 3330 VISIT_FOR_VALUE(expr->value()); |
| 3349 HValue* right = Pop(); | 3331 HValue* right = Pop(); |
| 3350 HValue* left = Pop(); | 3332 HValue* left = Pop(); |
| 3351 | 3333 |
| 3352 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 3334 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| 3353 PushAndAdd(instr); | 3335 PushAndAdd(instr); |
| 3354 if (instr->HasSideEffects()) AddSimulate(operation->id()); | 3336 if (instr->HasSideEffects()) AddSimulate(operation->id()); |
| 3355 | 3337 |
| 3356 HInstruction* store = is_fast_elements | 3338 HInstruction* store = BuildStoreKeyed(obj, key, instr, expr); |
| 3357 ? BuildStoreKeyedFastElement(obj, key, instr, prop) | |
| 3358 : BuildStoreKeyedGeneric(obj, key, instr); | |
| 3359 AddInstruction(store); | 3339 AddInstruction(store); |
| 3360 // Drop the simulated receiver, key, and value. Return the value. | 3340 // Drop the simulated receiver, key, and value. Return the value. |
| 3361 Drop(3); | 3341 Drop(3); |
| 3362 Push(instr); | 3342 Push(instr); |
| 3363 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3343 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| 3364 ast_context()->ReturnValue(Pop()); | 3344 ast_context()->ReturnValue(Pop()); |
| 3365 } | 3345 } |
| 3366 | 3346 |
| 3367 } else { | 3347 } else { |
| 3368 BAILOUT("invalid lhs in compound assignment"); | 3348 BAILOUT("invalid lhs in compound assignment"); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3551 AddInstruction(elements); | 3531 AddInstruction(elements); |
| 3552 HInstruction* length = new HExternalArrayLength(elements); | 3532 HInstruction* length = new HExternalArrayLength(elements); |
| 3553 AddInstruction(length); | 3533 AddInstruction(length); |
| 3554 AddInstruction(new HBoundsCheck(key, length)); | 3534 AddInstruction(new HBoundsCheck(key, length)); |
| 3555 HLoadExternalArrayPointer* external_elements = | 3535 HLoadExternalArrayPointer* external_elements = |
| 3556 new HLoadExternalArrayPointer(elements); | 3536 new HLoadExternalArrayPointer(elements); |
| 3557 AddInstruction(external_elements); | 3537 AddInstruction(external_elements); |
| 3558 HLoadKeyedSpecializedArrayElement* pixel_array_value = | 3538 HLoadKeyedSpecializedArrayElement* pixel_array_value = |
| 3559 new HLoadKeyedSpecializedArrayElement(external_elements, | 3539 new HLoadKeyedSpecializedArrayElement(external_elements, |
| 3560 key, | 3540 key, |
| 3561 expr->GetExternalArrayType()); | 3541 expr->external_array_type()); |
| 3562 return pixel_array_value; | 3542 return pixel_array_value; |
| 3563 } | 3543 } |
| 3564 | 3544 |
| 3565 | 3545 |
| 3546 HInstruction* HGraphBuilder::BuildLoadKeyed(HValue* obj, | |
| 3547 HValue* key, | |
| 3548 Property* prop) { | |
| 3549 if (prop->IsMonomorphic()) { | |
| 3550 Handle<Map> receiver_type(prop->GetMonomorphicReceiverType()); | |
| 3551 // An object has either fast elements or pixel array elements, but never | |
| 3552 // both. Pixel array maps that are assigned to pixel array elements are | |
| 3553 // always created with the fast elements flag cleared. | |
| 3554 if (receiver_type->has_external_array_elements()) { | |
| 3555 return BuildLoadKeyedSpecializedArrayElement(obj, key, prop); | |
| 3556 } else if (receiver_type->has_fast_elements()) { | |
| 3557 return BuildLoadKeyedFastElement(obj, key, prop); | |
| 3558 } | |
| 3559 } | |
| 3560 return BuildLoadKeyedGeneric(obj, key); | |
| 3561 } | |
| 3562 | |
| 3563 | |
| 3566 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, | 3564 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, |
| 3567 HValue* key, | 3565 HValue* key, |
| 3568 HValue* value) { | 3566 HValue* value) { |
| 3569 HContext* context = new HContext; | 3567 HContext* context = new HContext; |
| 3570 AddInstruction(context); | 3568 AddInstruction(context); |
| 3571 return new HStoreKeyedGeneric(context, object, key, value); | 3569 return new HStoreKeyedGeneric(context, object, key, value); |
| 3572 } | 3570 } |
| 3573 | 3571 |
| 3574 | 3572 |
| 3575 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object, | 3573 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement( |
| 3576 HValue* key, | 3574 HValue* object, |
| 3577 HValue* val, | 3575 HValue* key, |
| 3578 Expression* expr) { | 3576 HValue* val, |
| 3577 Expression* expr) { | |
| 3579 ASSERT(expr->IsMonomorphic()); | 3578 ASSERT(expr->IsMonomorphic()); |
| 3580 AddInstruction(new HCheckNonSmi(object)); | 3579 AddInstruction(new HCheckNonSmi(object)); |
| 3581 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 3580 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
| 3582 ASSERT(map->has_fast_elements()); | 3581 ASSERT(map->has_fast_elements()); |
| 3583 AddInstruction(new HCheckMap(object, map)); | 3582 AddInstruction(new HCheckMap(object, map)); |
| 3584 HInstruction* elements = AddInstruction(new HLoadElements(object)); | 3583 HInstruction* elements = AddInstruction(new HLoadElements(object)); |
| 3585 AddInstruction(new HCheckMap(elements, | 3584 AddInstruction(new HCheckMap(elements, |
| 3586 isolate()->factory()->fixed_array_map())); | 3585 isolate()->factory()->fixed_array_map())); |
| 3587 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); | 3586 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); |
| 3588 HInstruction* length = NULL; | 3587 HInstruction* length = NULL; |
| 3589 if (is_array) { | 3588 if (is_array) { |
| 3590 length = AddInstruction(new HJSArrayLength(object)); | 3589 length = AddInstruction(new HJSArrayLength(object)); |
| 3591 } else { | 3590 } else { |
| 3592 length = AddInstruction(new HFixedArrayLength(elements)); | 3591 length = AddInstruction(new HFixedArrayLength(elements)); |
| 3593 } | 3592 } |
| 3594 AddInstruction(new HBoundsCheck(key, length)); | 3593 AddInstruction(new HBoundsCheck(key, length)); |
| 3595 return new HStoreKeyedFastElement(elements, key, val); | 3594 return new HStoreKeyedFastElement(elements, key, val); |
| 3596 } | 3595 } |
| 3597 | 3596 |
| 3598 | 3597 |
| 3599 HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement( | 3598 HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement( |
| 3600 HValue* object, | 3599 HValue* object, |
| 3601 HValue* key, | 3600 HValue* key, |
| 3602 HValue* val, | 3601 HValue* val, |
| 3603 Assignment* expr) { | 3602 Expression* expr) { |
| 3604 ASSERT(expr->IsMonomorphic()); | 3603 ASSERT(expr->IsMonomorphic()); |
| 3605 AddInstruction(new HCheckNonSmi(object)); | 3604 AddInstruction(new HCheckNonSmi(object)); |
| 3606 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 3605 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
| 3607 ASSERT(!map->has_fast_elements()); | 3606 ASSERT(!map->has_fast_elements()); |
| 3608 ASSERT(map->has_external_array_elements()); | 3607 ASSERT(map->has_external_array_elements()); |
| 3609 AddInstruction(new HCheckMap(object, map)); | 3608 AddInstruction(new HCheckMap(object, map)); |
| 3610 HLoadElements* elements = new HLoadElements(object); | 3609 HLoadElements* elements = new HLoadElements(object); |
| 3611 AddInstruction(elements); | 3610 AddInstruction(elements); |
| 3612 HInstruction* length = AddInstruction(new HExternalArrayLength(elements)); | 3611 HInstruction* length = AddInstruction(new HExternalArrayLength(elements)); |
| 3613 AddInstruction(new HBoundsCheck(key, length)); | 3612 AddInstruction(new HBoundsCheck(key, length)); |
| 3614 HLoadExternalArrayPointer* external_elements = | 3613 HLoadExternalArrayPointer* external_elements = |
| 3615 new HLoadExternalArrayPointer(elements); | 3614 new HLoadExternalArrayPointer(elements); |
| 3616 AddInstruction(external_elements); | 3615 AddInstruction(external_elements); |
| 3617 return new HStoreKeyedSpecializedArrayElement( | 3616 return new HStoreKeyedSpecializedArrayElement(external_elements, |
| 3618 external_elements, | 3617 key, |
| 3619 key, | 3618 val, |
| 3620 val, | 3619 expr->external_array_type()); |
| 3621 expr->GetExternalArrayType()); | |
| 3622 } | 3620 } |
| 3623 | 3621 |
| 3624 | 3622 |
| 3623 HInstruction* HGraphBuilder::BuildStoreKeyed(HValue* object, | |
| 3624 HValue* key, | |
| 3625 HValue* value, | |
| 3626 Expression* expr) { | |
| 3627 if (expr->IsMonomorphic()) { | |
| 3628 Handle<Map> receiver_type(expr->GetMonomorphicReceiverType()); | |
| 3629 // An object has either fast elements or external array elements, but | |
| 3630 // never both. Pixel array maps that are assigned to pixel array elements | |
| 3631 // are always created with the fast elements flag cleared. | |
| 3632 if (receiver_type->has_external_array_elements()) { | |
| 3633 return BuildStoreKeyedSpecializedArrayElement(object, | |
| 3634 key, | |
| 3635 value, | |
| 3636 expr); | |
| 3637 } else if (receiver_type->has_fast_elements()) { | |
| 3638 return BuildStoreKeyedFastElement(object, key, value, expr); | |
| 3639 } | |
| 3640 } | |
| 3641 return BuildStoreKeyedGeneric(object, key, value); | |
| 3642 } | |
| 3643 | |
| 3644 | |
| 3625 bool HGraphBuilder::TryArgumentsAccess(Property* expr) { | 3645 bool HGraphBuilder::TryArgumentsAccess(Property* expr) { |
| 3626 VariableProxy* proxy = expr->obj()->AsVariableProxy(); | 3646 VariableProxy* proxy = expr->obj()->AsVariableProxy(); |
| 3627 if (proxy == NULL) return false; | 3647 if (proxy == NULL) return false; |
| 3628 if (!proxy->var()->IsStackAllocated()) return false; | 3648 if (!proxy->var()->IsStackAllocated()) return false; |
| 3629 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { | 3649 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { |
| 3630 return false; | 3650 return false; |
| 3631 } | 3651 } |
| 3632 | 3652 |
| 3633 HInstruction* result = NULL; | 3653 HInstruction* result = NULL; |
| 3634 if (expr->key()->IsPropertyName()) { | 3654 if (expr->key()->IsPropertyName()) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3699 instr = new HLoadNamedFieldPolymorphic(obj, types, name); | 3719 instr = new HLoadNamedFieldPolymorphic(obj, types, name); |
| 3700 } else { | 3720 } else { |
| 3701 instr = BuildLoadNamedGeneric(obj, expr); | 3721 instr = BuildLoadNamedGeneric(obj, expr); |
| 3702 } | 3722 } |
| 3703 | 3723 |
| 3704 } else { | 3724 } else { |
| 3705 VISIT_FOR_VALUE(expr->key()); | 3725 VISIT_FOR_VALUE(expr->key()); |
| 3706 | 3726 |
| 3707 HValue* key = Pop(); | 3727 HValue* key = Pop(); |
| 3708 HValue* obj = Pop(); | 3728 HValue* obj = Pop(); |
| 3709 | 3729 instr = BuildLoadKeyed(obj, key, expr); |
| 3710 if (expr->IsMonomorphic()) { | |
| 3711 Handle<Map> receiver_type(expr->GetMonomorphicReceiverType()); | |
| 3712 // An object has either fast elements or pixel array elements, but never | |
| 3713 // both. Pixel array maps that are assigned to pixel array elements are | |
| 3714 // always created with the fast elements flag cleared. | |
| 3715 if (receiver_type->has_external_array_elements()) { | |
| 3716 instr = BuildLoadKeyedSpecializedArrayElement(obj, key, expr); | |
| 3717 } else if (receiver_type->has_fast_elements()) { | |
| 3718 instr = BuildLoadKeyedFastElement(obj, key, expr); | |
| 3719 } | |
| 3720 } | |
| 3721 if (instr == NULL) { | |
| 3722 instr = BuildLoadKeyedGeneric(obj, key); | |
| 3723 } | |
| 3724 } | 3730 } |
| 3725 instr->set_position(expr->position()); | 3731 instr->set_position(expr->position()); |
| 3726 ast_context()->ReturnInstruction(instr, expr->id()); | 3732 ast_context()->ReturnInstruction(instr, expr->id()); |
| 3727 } | 3733 } |
| 3728 | 3734 |
| 3729 | 3735 |
| 3730 void HGraphBuilder::AddCheckConstantFunction(Call* expr, | 3736 void HGraphBuilder::AddCheckConstantFunction(Call* expr, |
| 3731 HValue* receiver, | 3737 HValue* receiver, |
| 3732 Handle<Map> receiver_map, | 3738 Handle<Map> receiver_map, |
| 3733 bool smi_and_map_check) { | 3739 bool smi_and_map_check) { |
| (...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4570 HStoreContextSlot* instr = new HStoreContextSlot(context, index, after); | 4576 HStoreContextSlot* instr = new HStoreContextSlot(context, index, after); |
| 4571 AddInstruction(instr); | 4577 AddInstruction(instr); |
| 4572 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 4578 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| 4573 } else { | 4579 } else { |
| 4574 BAILOUT("lookup variable in count operation"); | 4580 BAILOUT("lookup variable in count operation"); |
| 4575 } | 4581 } |
| 4576 Drop(has_extra ? 2 : 1); | 4582 Drop(has_extra ? 2 : 1); |
| 4577 ast_context()->ReturnValue(expr->is_postfix() ? before : after); | 4583 ast_context()->ReturnValue(expr->is_postfix() ? before : after); |
| 4578 | 4584 |
| 4579 } else if (prop != NULL) { | 4585 } else if (prop != NULL) { |
| 4580 prop->RecordTypeFeedback(oracle()); | 4586 prop->RecordTypeFeedback(oracle()); |
| 4587 expr->RecordTypeFeedback(oracle()); | |
|
Mads Ager (chromium)
2011/04/06 16:45:15
Move to where it is needed?
| |
| 4581 | 4588 |
| 4582 if (prop->key()->IsPropertyName()) { | 4589 if (prop->key()->IsPropertyName()) { |
| 4583 // Named property. | 4590 // Named property. |
| 4584 | 4591 |
| 4585 // Match the full code generator stack by simulating an extra stack | 4592 // Match the full code generator stack by simulating an extra stack |
| 4586 // element for postfix operations in a non-effect context. | 4593 // element for postfix operations in a non-effect context. |
| 4587 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); | 4594 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); |
| 4588 if (has_extra) Push(graph_->GetConstantUndefined()); | 4595 if (has_extra) Push(graph_->GetConstantUndefined()); |
| 4589 | 4596 |
| 4590 VISIT_FOR_VALUE(prop->obj()); | 4597 VISIT_FOR_VALUE(prop->obj()); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4626 // Match the full code generator stack by simulate an extra stack element | 4633 // Match the full code generator stack by simulate an extra stack element |
| 4627 // for postfix operations in a non-effect context. | 4634 // for postfix operations in a non-effect context. |
| 4628 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); | 4635 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); |
| 4629 if (has_extra) Push(graph_->GetConstantUndefined()); | 4636 if (has_extra) Push(graph_->GetConstantUndefined()); |
| 4630 | 4637 |
| 4631 VISIT_FOR_VALUE(prop->obj()); | 4638 VISIT_FOR_VALUE(prop->obj()); |
| 4632 VISIT_FOR_VALUE(prop->key()); | 4639 VISIT_FOR_VALUE(prop->key()); |
| 4633 HValue* obj = environment()->ExpressionStackAt(1); | 4640 HValue* obj = environment()->ExpressionStackAt(1); |
| 4634 HValue* key = environment()->ExpressionStackAt(0); | 4641 HValue* key = environment()->ExpressionStackAt(0); |
| 4635 | 4642 |
| 4636 bool is_fast_elements = prop->IsMonomorphic() && | 4643 HInstruction* load = BuildLoadKeyed(obj, key, prop); |
| 4637 prop->GetMonomorphicReceiverType()->has_fast_elements(); | |
| 4638 | |
| 4639 HInstruction* load = is_fast_elements | |
| 4640 ? BuildLoadKeyedFastElement(obj, key, prop) | |
| 4641 : BuildLoadKeyedGeneric(obj, key); | |
| 4642 PushAndAdd(load); | 4644 PushAndAdd(load); |
| 4643 if (load->HasSideEffects()) AddSimulate(increment->id()); | 4645 if (load->HasSideEffects()) AddSimulate(increment->id()); |
| 4644 | 4646 |
| 4645 HValue* before = Pop(); | 4647 HValue* before = Pop(); |
| 4646 // There is no deoptimization to after the increment, so we don't need | 4648 // There is no deoptimization to after the increment, so we don't need |
| 4647 // to simulate the expression stack after this instruction. | 4649 // to simulate the expression stack after this instruction. |
| 4648 HInstruction* after = BuildIncrement(before, inc); | 4650 HInstruction* after = BuildIncrement(before, inc); |
| 4649 AddInstruction(after); | 4651 AddInstruction(after); |
| 4650 | 4652 |
| 4651 HInstruction* store = is_fast_elements | 4653 HInstruction* store = BuildStoreKeyed(obj, key, after, expr); |
| 4652 ? BuildStoreKeyedFastElement(obj, key, after, prop) | |
| 4653 : BuildStoreKeyedGeneric(obj, key, after); | |
| 4654 AddInstruction(store); | 4654 AddInstruction(store); |
| 4655 | 4655 |
| 4656 // Drop the key from the bailout environment. Overwrite the receiver | 4656 // Drop the key from the bailout environment. Overwrite the receiver |
| 4657 // with the result of the operation, and the placeholder with the | 4657 // with the result of the operation, and the placeholder with the |
| 4658 // original value if necessary. | 4658 // original value if necessary. |
| 4659 Drop(1); | 4659 Drop(1); |
| 4660 environment()->SetExpressionStackAt(0, after); | 4660 environment()->SetExpressionStackAt(0, after); |
| 4661 if (has_extra) environment()->SetExpressionStackAt(1, before); | 4661 if (has_extra) environment()->SetExpressionStackAt(1, before); |
| 4662 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 4662 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| 4663 Drop(has_extra ? 2 : 1); | 4663 Drop(has_extra ? 2 : 1); |
| (...skipping 1227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5891 } | 5891 } |
| 5892 } | 5892 } |
| 5893 | 5893 |
| 5894 #ifdef DEBUG | 5894 #ifdef DEBUG |
| 5895 if (graph_ != NULL) graph_->Verify(); | 5895 if (graph_ != NULL) graph_->Verify(); |
| 5896 if (allocator_ != NULL) allocator_->Verify(); | 5896 if (allocator_ != NULL) allocator_->Verify(); |
| 5897 #endif | 5897 #endif |
| 5898 } | 5898 } |
| 5899 | 5899 |
| 5900 } } // namespace v8::internal | 5900 } } // namespace v8::internal |
| OLD | NEW |