| 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 3003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3014 | 3014 |
| 3015 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { | 3015 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 3016 HRegExpLiteral* instr = new HRegExpLiteral(expr->pattern(), | 3016 HRegExpLiteral* instr = new HRegExpLiteral(expr->pattern(), |
| 3017 expr->flags(), | 3017 expr->flags(), |
| 3018 expr->literal_index()); | 3018 expr->literal_index()); |
| 3019 ast_context()->ReturnInstruction(instr, expr->id()); | 3019 ast_context()->ReturnInstruction(instr, expr->id()); |
| 3020 } | 3020 } |
| 3021 | 3021 |
| 3022 | 3022 |
| 3023 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 3023 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
| 3024 HObjectLiteral* literal = (new HObjectLiteral(expr->constant_properties(), | 3024 HContext* context = new HContext; |
| 3025 AddInstruction(context); |
| 3026 HObjectLiteral* literal = (new HObjectLiteral(context, |
| 3027 expr->constant_properties(), |
| 3025 expr->fast_elements(), | 3028 expr->fast_elements(), |
| 3026 expr->literal_index(), | 3029 expr->literal_index(), |
| 3027 expr->depth())); | 3030 expr->depth())); |
| 3028 // The object is expected in the bailout environment during computation | 3031 // The object is expected in the bailout environment during computation |
| 3029 // of the property values and is the value of the entire expression. | 3032 // of the property values and is the value of the entire expression. |
| 3030 PushAndAdd(literal); | 3033 PushAndAdd(literal); |
| 3031 | 3034 |
| 3032 expr->CalculateEmitStore(); | 3035 expr->CalculateEmitStore(); |
| 3033 | 3036 |
| 3034 for (int i = 0; i < expr->properties()->length(); i++) { | 3037 for (int i = 0; i < expr->properties()->length(); i++) { |
| 3035 ObjectLiteral::Property* property = expr->properties()->at(i); | 3038 ObjectLiteral::Property* property = expr->properties()->at(i); |
| 3036 if (property->IsCompileTimeValue()) continue; | 3039 if (property->IsCompileTimeValue()) continue; |
| 3037 | 3040 |
| 3038 Literal* key = property->key(); | 3041 Literal* key = property->key(); |
| 3039 Expression* value = property->value(); | 3042 Expression* value = property->value(); |
| 3040 | 3043 |
| 3041 switch (property->kind()) { | 3044 switch (property->kind()) { |
| 3042 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 3045 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 3043 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 3046 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
| 3044 // Fall through. | 3047 // Fall through. |
| 3045 case ObjectLiteral::Property::COMPUTED: | 3048 case ObjectLiteral::Property::COMPUTED: |
| 3046 if (key->handle()->IsSymbol()) { | 3049 if (key->handle()->IsSymbol()) { |
| 3047 if (property->emit_store()) { | 3050 if (property->emit_store()) { |
| 3048 VISIT_FOR_VALUE(value); | 3051 VISIT_FOR_VALUE(value); |
| 3049 HValue* value = Pop(); | 3052 HValue* value = Pop(); |
| 3050 Handle<String> name = Handle<String>::cast(key->handle()); | 3053 Handle<String> name = Handle<String>::cast(key->handle()); |
| 3051 AddInstruction(new HStoreNamedGeneric(literal, name, value)); | 3054 HStoreNamedGeneric* store = |
| 3055 new HStoreNamedGeneric(context, literal, name, value); |
| 3056 AddInstruction(store); |
| 3052 AddSimulate(key->id()); | 3057 AddSimulate(key->id()); |
| 3053 } else { | 3058 } else { |
| 3054 VISIT_FOR_EFFECT(value); | 3059 VISIT_FOR_EFFECT(value); |
| 3055 } | 3060 } |
| 3056 break; | 3061 break; |
| 3057 } | 3062 } |
| 3058 // Fall through. | 3063 // Fall through. |
| 3059 case ObjectLiteral::Property::PROTOTYPE: | 3064 case ObjectLiteral::Property::PROTOTYPE: |
| 3060 case ObjectLiteral::Property::SETTER: | 3065 case ObjectLiteral::Property::SETTER: |
| 3061 case ObjectLiteral::Property::GETTER: | 3066 case ObjectLiteral::Property::GETTER: |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3221 // enable elimination of redundant checks after the transition store. | 3226 // enable elimination of redundant checks after the transition store. |
| 3222 instr->SetFlag(HValue::kChangesMaps); | 3227 instr->SetFlag(HValue::kChangesMaps); |
| 3223 } | 3228 } |
| 3224 return instr; | 3229 return instr; |
| 3225 } | 3230 } |
| 3226 | 3231 |
| 3227 | 3232 |
| 3228 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object, | 3233 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object, |
| 3229 Handle<String> name, | 3234 Handle<String> name, |
| 3230 HValue* value) { | 3235 HValue* value) { |
| 3231 return new HStoreNamedGeneric(object, name, value); | 3236 HContext* context = new HContext; |
| 3237 AddInstruction(context); |
| 3238 return new HStoreNamedGeneric(context, object, name, value); |
| 3232 } | 3239 } |
| 3233 | 3240 |
| 3234 | 3241 |
| 3235 HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, | 3242 HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, |
| 3236 HValue* value, | 3243 HValue* value, |
| 3237 Expression* expr) { | 3244 Expression* expr) { |
| 3238 Property* prop = (expr->AsProperty() != NULL) | 3245 Property* prop = (expr->AsProperty() != NULL) |
| 3239 ? expr->AsProperty() | 3246 ? expr->AsProperty() |
| 3240 : expr->AsAssignment()->target()->AsProperty(); | 3247 : expr->AsAssignment()->target()->AsProperty(); |
| 3241 Literal* key = prop->key()->AsLiteral(); | 3248 Literal* key = prop->key()->AsLiteral(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3283 AddInstruction(instr); | 3290 AddInstruction(instr); |
| 3284 subgraphs.Add(subgraph); | 3291 subgraphs.Add(subgraph); |
| 3285 } else { | 3292 } else { |
| 3286 needs_generic = true; | 3293 needs_generic = true; |
| 3287 } | 3294 } |
| 3288 } | 3295 } |
| 3289 | 3296 |
| 3290 // If none of the properties were named fields we generate a | 3297 // If none of the properties were named fields we generate a |
| 3291 // generic store. | 3298 // generic store. |
| 3292 if (maps.length() == 0) { | 3299 if (maps.length() == 0) { |
| 3293 HInstruction* instr = new HStoreNamedGeneric(object, name, value); | 3300 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); |
| 3294 Push(value); | 3301 Push(value); |
| 3295 instr->set_position(expr->position()); | 3302 instr->set_position(expr->position()); |
| 3296 AddInstruction(instr); | 3303 AddInstruction(instr); |
| 3297 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3304 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| 3298 ast_context()->ReturnValue(Pop()); | 3305 ast_context()->ReturnValue(Pop()); |
| 3299 } else { | 3306 } else { |
| 3300 // Build subgraph for generic store through IC. | 3307 // Build subgraph for generic store through IC. |
| 3301 { | 3308 { |
| 3302 HSubgraph* subgraph = CreateBranchSubgraph(environment()); | 3309 HSubgraph* subgraph = CreateBranchSubgraph(environment()); |
| 3303 SubgraphScope scope(this, subgraph); | 3310 SubgraphScope scope(this, subgraph); |
| 3304 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { | 3311 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { |
| 3305 subgraph->FinishExit(new HDeoptimize()); | 3312 subgraph->FinishExit(new HDeoptimize()); |
| 3306 } else { | 3313 } else { |
| 3307 HInstruction* instr = new HStoreNamedGeneric(object, name, value); | 3314 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); |
| 3308 Push(value); | 3315 Push(value); |
| 3309 instr->set_position(expr->position()); | 3316 instr->set_position(expr->position()); |
| 3310 AddInstruction(instr); | 3317 AddInstruction(instr); |
| 3311 } | 3318 } |
| 3312 subgraphs.Add(subgraph); | 3319 subgraphs.Add(subgraph); |
| 3313 } | 3320 } |
| 3314 | 3321 |
| 3315 HBasicBlock* new_exit_block = | 3322 HBasicBlock* new_exit_block = |
| 3316 BuildTypeSwitch(&maps, &subgraphs, object, expr->id()); | 3323 BuildTypeSwitch(&maps, &subgraphs, object, expr->id()); |
| 3317 subgraph()->set_exit_block(new_exit_block); | 3324 subgraph()->set_exit_block(new_exit_block); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3347 LookupResult lookup; | 3354 LookupResult lookup; |
| 3348 | 3355 |
| 3349 if (expr->IsMonomorphic()) { | 3356 if (expr->IsMonomorphic()) { |
| 3350 instr = BuildStoreNamed(object, value, expr); | 3357 instr = BuildStoreNamed(object, value, expr); |
| 3351 | 3358 |
| 3352 } else if (types != NULL && types->length() > 1) { | 3359 } else if (types != NULL && types->length() > 1) { |
| 3353 HandlePolymorphicStoreNamedField(expr, object, value, types, name); | 3360 HandlePolymorphicStoreNamedField(expr, object, value, types, name); |
| 3354 return; | 3361 return; |
| 3355 | 3362 |
| 3356 } else { | 3363 } else { |
| 3357 instr = new HStoreNamedGeneric(object, name, value); | 3364 instr = BuildStoreNamedGeneric(object, name, value); |
| 3358 } | 3365 } |
| 3359 | 3366 |
| 3360 } else { | 3367 } else { |
| 3361 // Keyed store. | 3368 // Keyed store. |
| 3362 VISIT_FOR_VALUE(prop->key()); | 3369 VISIT_FOR_VALUE(prop->key()); |
| 3363 VISIT_FOR_VALUE(expr->value()); | 3370 VISIT_FOR_VALUE(expr->value()); |
| 3364 value = Pop(); | 3371 value = Pop(); |
| 3365 HValue* key = Pop(); | 3372 HValue* key = Pop(); |
| 3366 HValue* object = Pop(); | 3373 HValue* object = Pop(); |
| 3367 | 3374 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3467 | 3474 |
| 3468 } else { | 3475 } else { |
| 3469 // Keyed property. | 3476 // Keyed property. |
| 3470 VISIT_FOR_VALUE(prop->obj()); | 3477 VISIT_FOR_VALUE(prop->obj()); |
| 3471 VISIT_FOR_VALUE(prop->key()); | 3478 VISIT_FOR_VALUE(prop->key()); |
| 3472 HValue* obj = environment()->ExpressionStackAt(1); | 3479 HValue* obj = environment()->ExpressionStackAt(1); |
| 3473 HValue* key = environment()->ExpressionStackAt(0); | 3480 HValue* key = environment()->ExpressionStackAt(0); |
| 3474 | 3481 |
| 3475 bool is_fast_elements = prop->IsMonomorphic() && | 3482 bool is_fast_elements = prop->IsMonomorphic() && |
| 3476 prop->GetMonomorphicReceiverType()->has_fast_elements(); | 3483 prop->GetMonomorphicReceiverType()->has_fast_elements(); |
| 3477 | |
| 3478 HInstruction* load = is_fast_elements | 3484 HInstruction* load = is_fast_elements |
| 3479 ? BuildLoadKeyedFastElement(obj, key, prop) | 3485 ? BuildLoadKeyedFastElement(obj, key, prop) |
| 3480 : BuildLoadKeyedGeneric(obj, key); | 3486 : BuildLoadKeyedGeneric(obj, key); |
| 3481 PushAndAdd(load); | 3487 PushAndAdd(load); |
| 3482 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); | 3488 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); |
| 3483 | 3489 |
| 3484 VISIT_FOR_VALUE(expr->value()); | 3490 VISIT_FOR_VALUE(expr->value()); |
| 3485 HValue* right = Pop(); | 3491 HValue* right = Pop(); |
| 3486 HValue* left = Pop(); | 3492 HValue* left = Pop(); |
| 3487 | 3493 |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3670 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; | 3676 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; |
| 3671 return new HLoadNamedField(object, false, offset); | 3677 return new HLoadNamedField(object, false, offset); |
| 3672 } | 3678 } |
| 3673 } | 3679 } |
| 3674 | 3680 |
| 3675 | 3681 |
| 3676 HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj, | 3682 HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj, |
| 3677 Property* expr) { | 3683 Property* expr) { |
| 3678 ASSERT(expr->key()->IsPropertyName()); | 3684 ASSERT(expr->key()->IsPropertyName()); |
| 3679 Handle<Object> name = expr->key()->AsLiteral()->handle(); | 3685 Handle<Object> name = expr->key()->AsLiteral()->handle(); |
| 3680 return new HLoadNamedGeneric(obj, name); | 3686 HContext* context = new HContext; |
| 3687 AddInstruction(context); |
| 3688 return new HLoadNamedGeneric(context, obj, name); |
| 3681 } | 3689 } |
| 3682 | 3690 |
| 3683 | 3691 |
| 3684 HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj, | 3692 HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj, |
| 3685 Property* expr, | 3693 Property* expr, |
| 3686 Handle<Map> map, | 3694 Handle<Map> map, |
| 3687 Handle<String> name) { | 3695 Handle<String> name) { |
| 3688 LookupResult lookup; | 3696 LookupResult lookup; |
| 3689 map->LookupInDescriptors(NULL, *name, &lookup); | 3697 map->LookupInDescriptors(NULL, *name, &lookup); |
| 3690 if (lookup.IsProperty() && lookup.type() == FIELD) { | 3698 if (lookup.IsProperty() && lookup.type() == FIELD) { |
| 3691 return BuildLoadNamedField(obj, | 3699 return BuildLoadNamedField(obj, |
| 3692 expr, | 3700 expr, |
| 3693 map, | 3701 map, |
| 3694 &lookup, | 3702 &lookup, |
| 3695 true); | 3703 true); |
| 3696 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) { | 3704 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) { |
| 3697 AddInstruction(new HCheckNonSmi(obj)); | 3705 AddInstruction(new HCheckNonSmi(obj)); |
| 3698 AddInstruction(new HCheckMap(obj, map)); | 3706 AddInstruction(new HCheckMap(obj, map)); |
| 3699 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); | 3707 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); |
| 3700 return new HConstant(function, Representation::Tagged()); | 3708 return new HConstant(function, Representation::Tagged()); |
| 3701 } else { | 3709 } else { |
| 3702 return BuildLoadNamedGeneric(obj, expr); | 3710 return BuildLoadNamedGeneric(obj, expr); |
| 3703 } | 3711 } |
| 3704 } | 3712 } |
| 3705 | 3713 |
| 3706 | 3714 |
| 3707 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 3715 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
| 3708 HValue* key) { | 3716 HValue* key) { |
| 3709 return new HLoadKeyedGeneric(object, key); | 3717 HContext* context = new HContext; |
| 3718 AddInstruction(context); |
| 3719 return new HLoadKeyedGeneric(context, object, key); |
| 3710 } | 3720 } |
| 3711 | 3721 |
| 3712 | 3722 |
| 3713 HInstruction* HGraphBuilder::BuildLoadKeyedFastElement(HValue* object, | 3723 HInstruction* HGraphBuilder::BuildLoadKeyedFastElement(HValue* object, |
| 3714 HValue* key, | 3724 HValue* key, |
| 3715 Property* expr) { | 3725 Property* expr) { |
| 3716 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); | 3726 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); |
| 3717 AddInstruction(new HCheckNonSmi(object)); | 3727 AddInstruction(new HCheckNonSmi(object)); |
| 3718 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 3728 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
| 3719 ASSERT(map->has_fast_elements()); | 3729 ASSERT(map->has_fast_elements()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3730 length = AddInstruction(new HFixedArrayLength(elements)); | 3740 length = AddInstruction(new HFixedArrayLength(elements)); |
| 3731 AddInstruction(new HBoundsCheck(key, length)); | 3741 AddInstruction(new HBoundsCheck(key, length)); |
| 3732 } | 3742 } |
| 3733 return new HLoadKeyedFastElement(elements, key); | 3743 return new HLoadKeyedFastElement(elements, key); |
| 3734 } | 3744 } |
| 3735 | 3745 |
| 3736 | 3746 |
| 3737 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, | 3747 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, |
| 3738 HValue* key, | 3748 HValue* key, |
| 3739 HValue* value) { | 3749 HValue* value) { |
| 3740 return new HStoreKeyedGeneric(object, key, value); | 3750 HContext* context = new HContext; |
| 3751 AddInstruction(context); |
| 3752 return new HStoreKeyedGeneric(context, object, key, value); |
| 3741 } | 3753 } |
| 3742 | 3754 |
| 3743 | 3755 |
| 3744 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object, | 3756 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object, |
| 3745 HValue* key, | 3757 HValue* key, |
| 3746 HValue* val, | 3758 HValue* val, |
| 3747 Expression* expr) { | 3759 Expression* expr) { |
| 3748 ASSERT(expr->IsMonomorphic()); | 3760 ASSERT(expr->IsMonomorphic()); |
| 3749 AddInstruction(new HCheckNonSmi(object)); | 3761 AddInstruction(new HCheckNonSmi(object)); |
| 3750 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 3762 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3909 } | 3921 } |
| 3910 subgraphs.Add(subgraph); | 3922 subgraphs.Add(subgraph); |
| 3911 } else { | 3923 } else { |
| 3912 needs_generic = true; | 3924 needs_generic = true; |
| 3913 } | 3925 } |
| 3914 } | 3926 } |
| 3915 | 3927 |
| 3916 // If we couldn't compute the target for any of the maps just perform an | 3928 // If we couldn't compute the target for any of the maps just perform an |
| 3917 // IC call. | 3929 // IC call. |
| 3918 if (maps.length() == 0) { | 3930 if (maps.length() == 0) { |
| 3919 HCall* call = new HCallNamed(name, argument_count); | 3931 HContext* context = new HContext; |
| 3932 AddInstruction(context); |
| 3933 HCall* call = new HCallNamed(context, name, argument_count); |
| 3920 call->set_position(expr->position()); | 3934 call->set_position(expr->position()); |
| 3921 ProcessCall(call); | 3935 ProcessCall(call); |
| 3922 ast_context()->ReturnInstruction(call, expr->id()); | 3936 ast_context()->ReturnInstruction(call, expr->id()); |
| 3923 } else { | 3937 } else { |
| 3924 // Build subgraph for generic call through IC. | 3938 // Build subgraph for generic call through IC. |
| 3925 { | 3939 { |
| 3926 HSubgraph* subgraph = CreateBranchSubgraph(environment()); | 3940 HSubgraph* subgraph = CreateBranchSubgraph(environment()); |
| 3927 SubgraphScope scope(this, subgraph); | 3941 SubgraphScope scope(this, subgraph); |
| 3928 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { | 3942 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { |
| 3929 subgraph->FinishExit(new HDeoptimize()); | 3943 subgraph->FinishExit(new HDeoptimize()); |
| 3930 } else { | 3944 } else { |
| 3931 HCall* call = new HCallNamed(name, argument_count); | 3945 HContext* context = new HContext; |
| 3946 AddInstruction(context); |
| 3947 HCall* call = new HCallNamed(context, name, argument_count); |
| 3932 call->set_position(expr->position()); | 3948 call->set_position(expr->position()); |
| 3933 ProcessCall(call); | 3949 ProcessCall(call); |
| 3934 PushAndAdd(call); | 3950 PushAndAdd(call); |
| 3935 } | 3951 } |
| 3936 subgraphs.Add(subgraph); | 3952 subgraphs.Add(subgraph); |
| 3937 } | 3953 } |
| 3938 | 3954 |
| 3939 HBasicBlock* new_exit_block = | 3955 HBasicBlock* new_exit_block = |
| 3940 BuildTypeSwitch(&maps, &subgraphs, receiver, expr->id()); | 3956 BuildTypeSwitch(&maps, &subgraphs, receiver, expr->id()); |
| 3941 subgraph()->set_exit_block(new_exit_block); | 3957 subgraph()->set_exit_block(new_exit_block); |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4341 VISIT_FOR_VALUE(prop->key()); | 4357 VISIT_FOR_VALUE(prop->key()); |
| 4342 // Push receiver and key like the non-optimized code generator expects it. | 4358 // Push receiver and key like the non-optimized code generator expects it. |
| 4343 HValue* key = Pop(); | 4359 HValue* key = Pop(); |
| 4344 HValue* receiver = Pop(); | 4360 HValue* receiver = Pop(); |
| 4345 Push(key); | 4361 Push(key); |
| 4346 Push(receiver); | 4362 Push(receiver); |
| 4347 | 4363 |
| 4348 VisitArgumentList(expr->arguments()); | 4364 VisitArgumentList(expr->arguments()); |
| 4349 CHECK_BAILOUT; | 4365 CHECK_BAILOUT; |
| 4350 | 4366 |
| 4351 call = new HCallKeyed(key, argument_count); | 4367 HContext* context = new HContext; |
| 4368 AddInstruction(context); |
| 4369 call = new HCallKeyed(context, key, argument_count); |
| 4352 call->set_position(expr->position()); | 4370 call->set_position(expr->position()); |
| 4353 ProcessCall(call); | 4371 ProcessCall(call); |
| 4354 Drop(1); // Key. | 4372 Drop(1); // Key. |
| 4355 ast_context()->ReturnInstruction(call, expr->id()); | 4373 ast_context()->ReturnInstruction(call, expr->id()); |
| 4356 return; | 4374 return; |
| 4357 } | 4375 } |
| 4358 | 4376 |
| 4359 // Named function call. | 4377 // Named function call. |
| 4360 expr->RecordTypeFeedback(oracle()); | 4378 expr->RecordTypeFeedback(oracle()); |
| 4361 | 4379 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4380 receiver_map, | 4398 receiver_map, |
| 4381 expr->check_type())) { | 4399 expr->check_type())) { |
| 4382 return; | 4400 return; |
| 4383 } | 4401 } |
| 4384 | 4402 |
| 4385 if (HasCustomCallGenerator(expr->target()) || | 4403 if (HasCustomCallGenerator(expr->target()) || |
| 4386 expr->check_type() != RECEIVER_MAP_CHECK) { | 4404 expr->check_type() != RECEIVER_MAP_CHECK) { |
| 4387 // When the target has a custom call IC generator, use the IC, | 4405 // When the target has a custom call IC generator, use the IC, |
| 4388 // because it is likely to generate better code. Also use the | 4406 // because it is likely to generate better code. Also use the |
| 4389 // IC when a primitive receiver check is required. | 4407 // IC when a primitive receiver check is required. |
| 4390 call = new HCallNamed(name, argument_count); | 4408 HContext* context = new HContext; |
| 4409 AddInstruction(context); |
| 4410 call = new HCallNamed(context, name, argument_count); |
| 4391 } else { | 4411 } else { |
| 4392 AddCheckConstantFunction(expr, receiver, receiver_map, true); | 4412 AddCheckConstantFunction(expr, receiver, receiver_map, true); |
| 4393 | 4413 |
| 4394 if (TryInline(expr)) { | 4414 if (TryInline(expr)) { |
| 4395 if (subgraph()->HasExit()) { | 4415 if (subgraph()->HasExit()) { |
| 4396 HValue* return_value = Pop(); | 4416 HValue* return_value = Pop(); |
| 4397 // If we inlined a function in a test context then we need to emit | 4417 // If we inlined a function in a test context then we need to emit |
| 4398 // a simulate here to shadow the ones at the end of the | 4418 // a simulate here to shadow the ones at the end of the |
| 4399 // predecessor blocks. Those environments contain the return | 4419 // predecessor blocks. Those environments contain the return |
| 4400 // value on top and do not correspond to any actual state of the | 4420 // value on top and do not correspond to any actual state of the |
| 4401 // unoptimized code. | 4421 // unoptimized code. |
| 4402 if (ast_context()->IsEffect()) AddSimulate(expr->id()); | 4422 if (ast_context()->IsEffect()) AddSimulate(expr->id()); |
| 4403 ast_context()->ReturnValue(return_value); | 4423 ast_context()->ReturnValue(return_value); |
| 4404 } | 4424 } |
| 4405 return; | 4425 return; |
| 4406 } else { | 4426 } else { |
| 4407 // Check for bailout, as the TryInline call in the if condition above | 4427 // Check for bailout, as the TryInline call in the if condition above |
| 4408 // might return false due to bailout during hydrogen processing. | 4428 // might return false due to bailout during hydrogen processing. |
| 4409 CHECK_BAILOUT; | 4429 CHECK_BAILOUT; |
| 4410 call = new HCallConstantFunction(expr->target(), argument_count); | 4430 call = new HCallConstantFunction(expr->target(), argument_count); |
| 4411 } | 4431 } |
| 4412 } | 4432 } |
| 4413 } else if (types != NULL && types->length() > 1) { | 4433 } else if (types != NULL && types->length() > 1) { |
| 4414 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); | 4434 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); |
| 4415 HandlePolymorphicCallNamed(expr, receiver, types, name); | 4435 HandlePolymorphicCallNamed(expr, receiver, types, name); |
| 4416 return; | 4436 return; |
| 4417 | 4437 |
| 4418 } else { | 4438 } else { |
| 4419 call = new HCallNamed(name, argument_count); | 4439 HContext* context = new HContext; |
| 4440 AddInstruction(context); |
| 4441 call = new HCallNamed(context, name, argument_count); |
| 4420 } | 4442 } |
| 4421 | 4443 |
| 4422 } else { | 4444 } else { |
| 4423 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); | 4445 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
| 4424 bool global_call = (var != NULL) && var->is_global() && !var->is_this(); | 4446 bool global_call = (var != NULL) && var->is_global() && !var->is_this(); |
| 4425 | 4447 |
| 4426 if (!global_call) { | 4448 if (!global_call) { |
| 4427 ++argument_count; | 4449 ++argument_count; |
| 4428 VisitArgument(expr->expression()); | 4450 VisitArgument(expr->expression()); |
| 4429 CHECK_BAILOUT; | 4451 CHECK_BAILOUT; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4479 CHECK_BAILOUT; | 4501 CHECK_BAILOUT; |
| 4480 | 4502 |
| 4481 call = new HCallKnownGlobal(expr->target(), argument_count); | 4503 call = new HCallKnownGlobal(expr->target(), argument_count); |
| 4482 } else { | 4504 } else { |
| 4483 HContext* context = new HContext; | 4505 HContext* context = new HContext; |
| 4484 AddInstruction(context); | 4506 AddInstruction(context); |
| 4485 PushAndAdd(new HGlobalObject(context)); | 4507 PushAndAdd(new HGlobalObject(context)); |
| 4486 VisitArgumentList(expr->arguments()); | 4508 VisitArgumentList(expr->arguments()); |
| 4487 CHECK_BAILOUT; | 4509 CHECK_BAILOUT; |
| 4488 | 4510 |
| 4489 call = new HCallGlobal(var->name(), argument_count); | 4511 call = new HCallGlobal(context, var->name(), argument_count); |
| 4490 } | 4512 } |
| 4491 | 4513 |
| 4492 } else { | 4514 } else { |
| 4493 HContext* context = new HContext; | 4515 HContext* context = new HContext; |
| 4494 HGlobalObject* global_object = new HGlobalObject(context); | 4516 HGlobalObject* global_object = new HGlobalObject(context); |
| 4495 AddInstruction(context); | 4517 AddInstruction(context); |
| 4496 AddInstruction(global_object); | 4518 AddInstruction(global_object); |
| 4497 PushAndAdd(new HGlobalReceiver(global_object)); | 4519 PushAndAdd(new HGlobalReceiver(global_object)); |
| 4498 VisitArgumentList(expr->arguments()); | 4520 VisitArgumentList(expr->arguments()); |
| 4499 CHECK_BAILOUT; | 4521 CHECK_BAILOUT; |
| 4500 | 4522 |
| 4501 call = new HCallFunction(argument_count); | 4523 call = new HCallFunction(context, argument_count); |
| 4502 } | 4524 } |
| 4503 } | 4525 } |
| 4504 | 4526 |
| 4505 call->set_position(expr->position()); | 4527 call->set_position(expr->position()); |
| 4506 ProcessCall(call); | 4528 ProcessCall(call); |
| 4507 ast_context()->ReturnInstruction(call, expr->id()); | 4529 ast_context()->ReturnInstruction(call, expr->id()); |
| 4508 } | 4530 } |
| 4509 | 4531 |
| 4510 | 4532 |
| 4511 void HGraphBuilder::VisitCallNew(CallNew* expr) { | 4533 void HGraphBuilder::VisitCallNew(CallNew* expr) { |
| 4512 // The constructor function is also used as the receiver argument to the | 4534 // The constructor function is also used as the receiver argument to the |
| 4513 // JS construct call builtin. | 4535 // JS construct call builtin. |
| 4514 VisitArgument(expr->expression()); | 4536 VisitArgument(expr->expression()); |
| 4515 CHECK_BAILOUT; | 4537 CHECK_BAILOUT; |
| 4516 VisitArgumentList(expr->arguments()); | 4538 VisitArgumentList(expr->arguments()); |
| 4517 CHECK_BAILOUT; | 4539 CHECK_BAILOUT; |
| 4518 | 4540 |
| 4519 int argument_count = expr->arguments()->length() + 1; // Plus constructor. | 4541 int argument_count = expr->arguments()->length() + 1; // Plus constructor. |
| 4520 HCall* call = new HCallNew(argument_count); | 4542 HContext* context = new HContext; |
| 4543 AddInstruction(context); |
| 4544 HCall* call = new HCallNew(context, argument_count); |
| 4521 call->set_position(expr->position()); | 4545 call->set_position(expr->position()); |
| 4522 ProcessCall(call); | 4546 ProcessCall(call); |
| 4523 ast_context()->ReturnInstruction(call, expr->id()); | 4547 ast_context()->ReturnInstruction(call, expr->id()); |
| 4524 } | 4548 } |
| 4525 | 4549 |
| 4526 | 4550 |
| 4527 // Support for generating inlined runtime functions. | 4551 // Support for generating inlined runtime functions. |
| 4528 | 4552 |
| 4529 // Lookup table for generators for runtime calls that are generated inline. | 4553 // Lookup table for generators for runtime calls that are generated inline. |
| 4530 // Elements of the table are member pointers to functions of HGraphBuilder. | 4554 // Elements of the table are member pointers to functions of HGraphBuilder. |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4778 if (load->HasSideEffects()) AddSimulate(increment->id()); | 4802 if (load->HasSideEffects()) AddSimulate(increment->id()); |
| 4779 | 4803 |
| 4780 HValue* before = Pop(); | 4804 HValue* before = Pop(); |
| 4781 // There is no deoptimization to after the increment, so we don't need | 4805 // There is no deoptimization to after the increment, so we don't need |
| 4782 // to simulate the expression stack after this instruction. | 4806 // to simulate the expression stack after this instruction. |
| 4783 HInstruction* after = BuildIncrement(before, inc); | 4807 HInstruction* after = BuildIncrement(before, inc); |
| 4784 AddInstruction(after); | 4808 AddInstruction(after); |
| 4785 | 4809 |
| 4786 HInstruction* store = is_fast_elements | 4810 HInstruction* store = is_fast_elements |
| 4787 ? BuildStoreKeyedFastElement(obj, key, after, prop) | 4811 ? BuildStoreKeyedFastElement(obj, key, after, prop) |
| 4788 : new HStoreKeyedGeneric(obj, key, after); | 4812 : BuildStoreKeyedGeneric(obj, key, after); |
| 4789 AddInstruction(store); | 4813 AddInstruction(store); |
| 4790 | 4814 |
| 4791 // Drop the key from the bailout environment. Overwrite the receiver | 4815 // Drop the key from the bailout environment. Overwrite the receiver |
| 4792 // with the result of the operation, and the placeholder with the | 4816 // with the result of the operation, and the placeholder with the |
| 4793 // original value if necessary. | 4817 // original value if necessary. |
| 4794 Drop(1); | 4818 Drop(1); |
| 4795 environment()->SetExpressionStackAt(0, after); | 4819 environment()->SetExpressionStackAt(0, after); |
| 4796 if (has_extra) environment()->SetExpressionStackAt(1, before); | 4820 if (has_extra) environment()->SetExpressionStackAt(1, before); |
| 4797 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 4821 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| 4798 Drop(has_extra ? 2 : 1); | 4822 Drop(has_extra ? 2 : 1); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5035 // change and thus prefer the general IC code. | 5059 // change and thus prefer the general IC code. |
| 5036 if (!Heap::InNewSpace(*candidate)) { | 5060 if (!Heap::InNewSpace(*candidate)) { |
| 5037 target = candidate; | 5061 target = candidate; |
| 5038 } | 5062 } |
| 5039 } | 5063 } |
| 5040 } | 5064 } |
| 5041 | 5065 |
| 5042 // If the target is not null we have found a known global function that is | 5066 // If the target is not null we have found a known global function that is |
| 5043 // assumed to stay the same for this instanceof. | 5067 // assumed to stay the same for this instanceof. |
| 5044 if (target.is_null()) { | 5068 if (target.is_null()) { |
| 5045 instr = new HInstanceOf(left, right); | 5069 HContext* context = new HContext; |
| 5070 AddInstruction(context); |
| 5071 instr = new HInstanceOf(context, left, right); |
| 5046 } else { | 5072 } else { |
| 5047 AddInstruction(new HCheckFunction(right, target)); | 5073 AddInstruction(new HCheckFunction(right, target)); |
| 5048 instr = new HInstanceOfKnownGlobal(left, target); | 5074 instr = new HInstanceOfKnownGlobal(left, target); |
| 5049 } | 5075 } |
| 5050 } else if (op == Token::IN) { | 5076 } else if (op == Token::IN) { |
| 5051 BAILOUT("Unsupported comparison: in"); | 5077 BAILOUT("Unsupported comparison: in"); |
| 5052 } else if (info.IsNonPrimitive()) { | 5078 } else if (info.IsNonPrimitive()) { |
| 5053 switch (op) { | 5079 switch (op) { |
| 5054 case Token::EQ: | 5080 case Token::EQ: |
| 5055 case Token::EQ_STRICT: { | 5081 case Token::EQ_STRICT: { |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5246 void HGraphBuilder::GenerateStringCharFromCode(int argument_count, | 5272 void HGraphBuilder::GenerateStringCharFromCode(int argument_count, |
| 5247 int ast_id) { | 5273 int ast_id) { |
| 5248 BAILOUT("inlined runtime function: StringCharFromCode"); | 5274 BAILOUT("inlined runtime function: StringCharFromCode"); |
| 5249 } | 5275 } |
| 5250 | 5276 |
| 5251 | 5277 |
| 5252 // Fast support for string.charAt(n) and string[n]. | 5278 // Fast support for string.charAt(n) and string[n]. |
| 5253 void HGraphBuilder::GenerateStringCharAt(int argument_count, int ast_id) { | 5279 void HGraphBuilder::GenerateStringCharAt(int argument_count, int ast_id) { |
| 5254 ASSERT_EQ(2, argument_count); | 5280 ASSERT_EQ(2, argument_count); |
| 5255 PushArgumentsForStubCall(argument_count); | 5281 PushArgumentsForStubCall(argument_count); |
| 5256 HCallStub* result = new HCallStub(CodeStub::StringCharAt, argument_count); | 5282 HContext* context = new HContext; |
| 5283 AddInstruction(context); |
| 5284 HCallStub* result = |
| 5285 new HCallStub(context, CodeStub::StringCharAt, argument_count); |
| 5257 ast_context()->ReturnInstruction(result, ast_id); | 5286 ast_context()->ReturnInstruction(result, ast_id); |
| 5258 } | 5287 } |
| 5259 | 5288 |
| 5260 | 5289 |
| 5261 // Fast support for object equality testing. | 5290 // Fast support for object equality testing. |
| 5262 void HGraphBuilder::GenerateObjectEquals(int argument_count, int ast_id) { | 5291 void HGraphBuilder::GenerateObjectEquals(int argument_count, int ast_id) { |
| 5263 ASSERT(argument_count == 2); | 5292 ASSERT(argument_count == 2); |
| 5264 HValue* right = Pop(); | 5293 HValue* right = Pop(); |
| 5265 HValue* left = Pop(); | 5294 HValue* left = Pop(); |
| 5266 HCompareJSObjectEq* result = new HCompareJSObjectEq(left, right); | 5295 HCompareJSObjectEq* result = new HCompareJSObjectEq(left, right); |
| 5267 ast_context()->ReturnInstruction(result, ast_id); | 5296 ast_context()->ReturnInstruction(result, ast_id); |
| 5268 } | 5297 } |
| 5269 | 5298 |
| 5270 | 5299 |
| 5271 void HGraphBuilder::GenerateLog(int argument_count, int ast_id) { | 5300 void HGraphBuilder::GenerateLog(int argument_count, int ast_id) { |
| 5272 UNREACHABLE(); // We caught this in VisitCallRuntime. | 5301 UNREACHABLE(); // We caught this in VisitCallRuntime. |
| 5273 } | 5302 } |
| 5274 | 5303 |
| 5275 | 5304 |
| 5276 // Fast support for Math.random(). | 5305 // Fast support for Math.random(). |
| 5277 void HGraphBuilder::GenerateRandomHeapNumber(int argument_count, int ast_id) { | 5306 void HGraphBuilder::GenerateRandomHeapNumber(int argument_count, int ast_id) { |
| 5278 BAILOUT("inlined runtime function: RandomHeapNumber"); | 5307 BAILOUT("inlined runtime function: RandomHeapNumber"); |
| 5279 } | 5308 } |
| 5280 | 5309 |
| 5281 | 5310 |
| 5282 // Fast support for StringAdd. | 5311 // Fast support for StringAdd. |
| 5283 void HGraphBuilder::GenerateStringAdd(int argument_count, int ast_id) { | 5312 void HGraphBuilder::GenerateStringAdd(int argument_count, int ast_id) { |
| 5284 ASSERT_EQ(2, argument_count); | 5313 ASSERT_EQ(2, argument_count); |
| 5285 PushArgumentsForStubCall(argument_count); | 5314 PushArgumentsForStubCall(argument_count); |
| 5286 HCallStub* result = new HCallStub(CodeStub::StringAdd, argument_count); | 5315 HContext* context = new HContext; |
| 5316 AddInstruction(context); |
| 5317 HCallStub* result = |
| 5318 new HCallStub(context, CodeStub::StringAdd, argument_count); |
| 5287 ast_context()->ReturnInstruction(result, ast_id); | 5319 ast_context()->ReturnInstruction(result, ast_id); |
| 5288 } | 5320 } |
| 5289 | 5321 |
| 5290 | 5322 |
| 5291 // Fast support for SubString. | 5323 // Fast support for SubString. |
| 5292 void HGraphBuilder::GenerateSubString(int argument_count, int ast_id) { | 5324 void HGraphBuilder::GenerateSubString(int argument_count, int ast_id) { |
| 5293 ASSERT_EQ(3, argument_count); | 5325 ASSERT_EQ(3, argument_count); |
| 5294 PushArgumentsForStubCall(argument_count); | 5326 PushArgumentsForStubCall(argument_count); |
| 5295 HCallStub* result = new HCallStub(CodeStub::SubString, argument_count); | 5327 HContext* context = new HContext; |
| 5328 AddInstruction(context); |
| 5329 HCallStub* result = |
| 5330 new HCallStub(context, CodeStub::SubString, argument_count); |
| 5296 ast_context()->ReturnInstruction(result, ast_id); | 5331 ast_context()->ReturnInstruction(result, ast_id); |
| 5297 } | 5332 } |
| 5298 | 5333 |
| 5299 | 5334 |
| 5300 // Fast support for StringCompare. | 5335 // Fast support for StringCompare. |
| 5301 void HGraphBuilder::GenerateStringCompare(int argument_count, int ast_id) { | 5336 void HGraphBuilder::GenerateStringCompare(int argument_count, int ast_id) { |
| 5302 ASSERT_EQ(2, argument_count); | 5337 ASSERT_EQ(2, argument_count); |
| 5303 PushArgumentsForStubCall(argument_count); | 5338 PushArgumentsForStubCall(argument_count); |
| 5304 HCallStub* result = new HCallStub(CodeStub::StringCompare, argument_count); | 5339 HContext* context = new HContext; |
| 5340 AddInstruction(context); |
| 5341 HCallStub* result = |
| 5342 new HCallStub(context, CodeStub::StringCompare, argument_count); |
| 5305 ast_context()->ReturnInstruction(result, ast_id); | 5343 ast_context()->ReturnInstruction(result, ast_id); |
| 5306 } | 5344 } |
| 5307 | 5345 |
| 5308 | 5346 |
| 5309 // Support for direct calls from JavaScript to native RegExp code. | 5347 // Support for direct calls from JavaScript to native RegExp code. |
| 5310 void HGraphBuilder::GenerateRegExpExec(int argument_count, int ast_id) { | 5348 void HGraphBuilder::GenerateRegExpExec(int argument_count, int ast_id) { |
| 5311 ASSERT_EQ(4, argument_count); | 5349 ASSERT_EQ(4, argument_count); |
| 5312 PushArgumentsForStubCall(argument_count); | 5350 PushArgumentsForStubCall(argument_count); |
| 5313 HCallStub* result = new HCallStub(CodeStub::RegExpExec, argument_count); | 5351 HContext* context = new HContext; |
| 5352 AddInstruction(context); |
| 5353 HCallStub* result = |
| 5354 new HCallStub(context, CodeStub::RegExpExec, argument_count); |
| 5314 ast_context()->ReturnInstruction(result, ast_id); | 5355 ast_context()->ReturnInstruction(result, ast_id); |
| 5315 } | 5356 } |
| 5316 | 5357 |
| 5317 | 5358 |
| 5318 // Construct a RegExp exec result with two in-object properties. | 5359 // Construct a RegExp exec result with two in-object properties. |
| 5319 void HGraphBuilder::GenerateRegExpConstructResult(int argument_count, | 5360 void HGraphBuilder::GenerateRegExpConstructResult(int argument_count, |
| 5320 int ast_id) { | 5361 int ast_id) { |
| 5321 ASSERT_EQ(3, argument_count); | 5362 ASSERT_EQ(3, argument_count); |
| 5322 PushArgumentsForStubCall(argument_count); | 5363 PushArgumentsForStubCall(argument_count); |
| 5364 HContext* context = new HContext; |
| 5365 AddInstruction(context); |
| 5323 HCallStub* result = | 5366 HCallStub* result = |
| 5324 new HCallStub(CodeStub::RegExpConstructResult, argument_count); | 5367 new HCallStub(context,CodeStub::RegExpConstructResult, argument_count); |
| 5325 ast_context()->ReturnInstruction(result, ast_id); | 5368 ast_context()->ReturnInstruction(result, ast_id); |
| 5326 } | 5369 } |
| 5327 | 5370 |
| 5328 | 5371 |
| 5329 // Support for fast native caches. | 5372 // Support for fast native caches. |
| 5330 void HGraphBuilder::GenerateGetFromCache(int argument_count, int ast_id) { | 5373 void HGraphBuilder::GenerateGetFromCache(int argument_count, int ast_id) { |
| 5331 BAILOUT("inlined runtime function: GetFromCache"); | 5374 BAILOUT("inlined runtime function: GetFromCache"); |
| 5332 } | 5375 } |
| 5333 | 5376 |
| 5334 | 5377 |
| 5335 // Fast support for number to string. | 5378 // Fast support for number to string. |
| 5336 void HGraphBuilder::GenerateNumberToString(int argument_count, int ast_id) { | 5379 void HGraphBuilder::GenerateNumberToString(int argument_count, int ast_id) { |
| 5337 ASSERT_EQ(1, argument_count); | 5380 ASSERT_EQ(1, argument_count); |
| 5338 PushArgumentsForStubCall(argument_count); | 5381 PushArgumentsForStubCall(argument_count); |
| 5339 HCallStub* result = new HCallStub(CodeStub::NumberToString, argument_count); | 5382 HContext* context = new HContext; |
| 5383 AddInstruction(context); |
| 5384 HCallStub* result = |
| 5385 new HCallStub(context, CodeStub::NumberToString, argument_count); |
| 5340 ast_context()->ReturnInstruction(result, ast_id); | 5386 ast_context()->ReturnInstruction(result, ast_id); |
| 5341 } | 5387 } |
| 5342 | 5388 |
| 5343 | 5389 |
| 5344 // Fast swapping of elements. Takes three expressions, the object and two | 5390 // Fast swapping of elements. Takes three expressions, the object and two |
| 5345 // indices. This should only be used if the indices are known to be | 5391 // indices. This should only be used if the indices are known to be |
| 5346 // non-negative and within bounds of the elements array at the call site. | 5392 // non-negative and within bounds of the elements array at the call site. |
| 5347 void HGraphBuilder::GenerateSwapElements(int argument_count, int ast_id) { | 5393 void HGraphBuilder::GenerateSwapElements(int argument_count, int ast_id) { |
| 5348 BAILOUT("inlined runtime function: SwapElements"); | 5394 BAILOUT("inlined runtime function: SwapElements"); |
| 5349 } | 5395 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5361 HValue* right = Pop(); | 5407 HValue* right = Pop(); |
| 5362 HValue* left = Pop(); | 5408 HValue* left = Pop(); |
| 5363 HPower* result = new HPower(left, right); | 5409 HPower* result = new HPower(left, right); |
| 5364 ast_context()->ReturnInstruction(result, ast_id); | 5410 ast_context()->ReturnInstruction(result, ast_id); |
| 5365 } | 5411 } |
| 5366 | 5412 |
| 5367 | 5413 |
| 5368 void HGraphBuilder::GenerateMathSin(int argument_count, int ast_id) { | 5414 void HGraphBuilder::GenerateMathSin(int argument_count, int ast_id) { |
| 5369 ASSERT_EQ(1, argument_count); | 5415 ASSERT_EQ(1, argument_count); |
| 5370 PushArgumentsForStubCall(argument_count); | 5416 PushArgumentsForStubCall(argument_count); |
| 5417 HContext* context = new HContext; |
| 5418 AddInstruction(context); |
| 5371 HCallStub* result = | 5419 HCallStub* result = |
| 5372 new HCallStub(CodeStub::TranscendentalCache, argument_count); | 5420 new HCallStub(context, CodeStub::TranscendentalCache, argument_count); |
| 5373 result->set_transcendental_type(TranscendentalCache::SIN); | 5421 result->set_transcendental_type(TranscendentalCache::SIN); |
| 5374 ast_context()->ReturnInstruction(result, ast_id); | 5422 ast_context()->ReturnInstruction(result, ast_id); |
| 5375 } | 5423 } |
| 5376 | 5424 |
| 5377 | 5425 |
| 5378 void HGraphBuilder::GenerateMathCos(int argument_count, int ast_id) { | 5426 void HGraphBuilder::GenerateMathCos(int argument_count, int ast_id) { |
| 5379 ASSERT_EQ(1, argument_count); | 5427 ASSERT_EQ(1, argument_count); |
| 5380 PushArgumentsForStubCall(argument_count); | 5428 PushArgumentsForStubCall(argument_count); |
| 5429 HContext* context = new HContext; |
| 5430 AddInstruction(context); |
| 5381 HCallStub* result = | 5431 HCallStub* result = |
| 5382 new HCallStub(CodeStub::TranscendentalCache, argument_count); | 5432 new HCallStub(context, CodeStub::TranscendentalCache, argument_count); |
| 5383 result->set_transcendental_type(TranscendentalCache::COS); | 5433 result->set_transcendental_type(TranscendentalCache::COS); |
| 5384 ast_context()->ReturnInstruction(result, ast_id); | 5434 ast_context()->ReturnInstruction(result, ast_id); |
| 5385 } | 5435 } |
| 5386 | 5436 |
| 5387 | 5437 |
| 5388 void HGraphBuilder::GenerateMathLog(int argument_count, int ast_id) { | 5438 void HGraphBuilder::GenerateMathLog(int argument_count, int ast_id) { |
| 5389 ASSERT_EQ(1, argument_count); | 5439 ASSERT_EQ(1, argument_count); |
| 5390 PushArgumentsForStubCall(argument_count); | 5440 PushArgumentsForStubCall(argument_count); |
| 5441 HContext* context = new HContext; |
| 5442 AddInstruction(context); |
| 5391 HCallStub* result = | 5443 HCallStub* result = |
| 5392 new HCallStub(CodeStub::TranscendentalCache, argument_count); | 5444 new HCallStub(context, CodeStub::TranscendentalCache, argument_count); |
| 5393 result->set_transcendental_type(TranscendentalCache::LOG); | 5445 result->set_transcendental_type(TranscendentalCache::LOG); |
| 5394 ast_context()->ReturnInstruction(result, ast_id); | 5446 ast_context()->ReturnInstruction(result, ast_id); |
| 5395 } | 5447 } |
| 5396 | 5448 |
| 5397 | 5449 |
| 5398 void HGraphBuilder::GenerateMathSqrt(int argument_count, int ast_id) { | 5450 void HGraphBuilder::GenerateMathSqrt(int argument_count, int ast_id) { |
| 5399 BAILOUT("inlined runtime function: MathSqrt"); | 5451 BAILOUT("inlined runtime function: MathSqrt"); |
| 5400 } | 5452 } |
| 5401 | 5453 |
| 5402 | 5454 |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5925 } | 5977 } |
| 5926 } | 5978 } |
| 5927 | 5979 |
| 5928 #ifdef DEBUG | 5980 #ifdef DEBUG |
| 5929 if (graph_ != NULL) graph_->Verify(); | 5981 if (graph_ != NULL) graph_->Verify(); |
| 5930 if (allocator_ != NULL) allocator_->Verify(); | 5982 if (allocator_ != NULL) allocator_->Verify(); |
| 5931 #endif | 5983 #endif |
| 5932 } | 5984 } |
| 5933 | 5985 |
| 5934 } } // namespace v8::internal | 5986 } } // namespace v8::internal |
| OLD | NEW |