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 2211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2222 // We don't yet handle the function name for named function expressions. | 2222 // We don't yet handle the function name for named function expressions. |
2223 if (scope->function() != NULL) return Bailout("named function expression"); | 2223 if (scope->function() != NULL) return Bailout("named function expression"); |
2224 | 2224 |
2225 HConstant* undefined_constant = new(zone()) HConstant( | 2225 HConstant* undefined_constant = new(zone()) HConstant( |
2226 isolate()->factory()->undefined_value(), Representation::Tagged()); | 2226 isolate()->factory()->undefined_value(), Representation::Tagged()); |
2227 AddInstruction(undefined_constant); | 2227 AddInstruction(undefined_constant); |
2228 graph_->set_undefined_constant(undefined_constant); | 2228 graph_->set_undefined_constant(undefined_constant); |
2229 | 2229 |
2230 // Set the initial values of parameters including "this". "This" has | 2230 // Set the initial values of parameters including "this". "This" has |
2231 // parameter index 0. | 2231 // parameter index 0. |
2232 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); | 2232 int count = scope->num_parameters() + 1; |
2233 | 2233 for (int i = 0; i < count; ++i) { |
2234 for (int i = 0; i < environment()->parameter_count(); ++i) { | |
2235 HInstruction* parameter = AddInstruction(new(zone()) HParameter(i)); | 2234 HInstruction* parameter = AddInstruction(new(zone()) HParameter(i)); |
2236 environment()->Bind(i, parameter); | 2235 environment()->Bind(i, parameter); |
2237 } | 2236 } |
2238 | 2237 |
2239 // First special is HContext. | 2238 // Set the initial values of stack-allocated locals. |
2240 HInstruction* context = AddInstruction(new(zone()) HContext); | 2239 for (int i = count; i < environment()->length(); ++i) { |
2241 environment()->BindContext(context); | |
2242 | |
2243 // Initialize specials and locals to undefined. | |
2244 for (int i = environment()->parameter_count() + 1; | |
2245 i < environment()->length(); | |
2246 ++i) { | |
2247 environment()->Bind(i, undefined_constant); | 2240 environment()->Bind(i, undefined_constant); |
2248 } | 2241 } |
2249 | 2242 |
2250 // Handle the arguments and arguments shadow variables specially (they do | 2243 // Handle the arguments and arguments shadow variables specially (they do |
2251 // not have declarations). | 2244 // not have declarations). |
2252 if (scope->arguments() != NULL) { | 2245 if (scope->arguments() != NULL) { |
2253 if (!scope->arguments()->IsStackAllocated() || | 2246 if (!scope->arguments()->IsStackAllocated() || |
2254 (scope->arguments_shadow() != NULL && | 2247 (scope->arguments_shadow() != NULL && |
2255 !scope->arguments_shadow()->IsStackAllocated())) { | 2248 !scope->arguments_shadow()->IsStackAllocated())) { |
2256 return Bailout("context-allocated arguments"); | 2249 return Bailout("context-allocated arguments"); |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2593 HTest* test = new(zone()) HTest(true_value, non_osr_entry, osr_entry); | 2586 HTest* test = new(zone()) HTest(true_value, non_osr_entry, osr_entry); |
2594 current_block()->Finish(test); | 2587 current_block()->Finish(test); |
2595 | 2588 |
2596 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 2589 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
2597 non_osr_entry->Goto(loop_predecessor); | 2590 non_osr_entry->Goto(loop_predecessor); |
2598 | 2591 |
2599 set_current_block(osr_entry); | 2592 set_current_block(osr_entry); |
2600 int osr_entry_id = statement->OsrEntryId(); | 2593 int osr_entry_id = statement->OsrEntryId(); |
2601 // We want the correct environment at the OsrEntry instruction. Build | 2594 // We want the correct environment at the OsrEntry instruction. Build |
2602 // it explicitly. The expression stack should be empty. | 2595 // it explicitly. The expression stack should be empty. |
2603 ASSERT(environment()->ExpressionStackIsEmpty()); | 2596 int count = environment()->length(); |
2604 for (int i = 0; i < environment()->length(); ++i) { | 2597 ASSERT(count == |
2605 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 2598 (environment()->parameter_count() + environment()->local_count())); |
2606 AddInstruction(osr_value); | 2599 for (int i = 0; i < count; ++i) { |
2607 environment()->Bind(i, osr_value); | 2600 HUnknownOSRValue* unknown = new(zone()) HUnknownOSRValue; |
| 2601 AddInstruction(unknown); |
| 2602 environment()->Bind(i, unknown); |
2608 } | 2603 } |
2609 | 2604 |
2610 AddSimulate(osr_entry_id); | 2605 AddSimulate(osr_entry_id); |
2611 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); | 2606 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); |
2612 HContext* context = new(zone()) HContext; | |
2613 AddInstruction(context); | |
2614 environment()->BindContext(context); | |
2615 current_block()->Goto(loop_predecessor); | 2607 current_block()->Goto(loop_predecessor); |
2616 loop_predecessor->SetJoinId(statement->EntryId()); | 2608 loop_predecessor->SetJoinId(statement->EntryId()); |
2617 set_current_block(loop_predecessor); | 2609 set_current_block(loop_predecessor); |
2618 } | 2610 } |
2619 | 2611 |
2620 | 2612 |
2621 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 2613 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
2622 ASSERT(!HasStackOverflow()); | 2614 ASSERT(!HasStackOverflow()); |
2623 ASSERT(current_block() != NULL); | 2615 ASSERT(current_block() != NULL); |
2624 ASSERT(current_block()->HasPredecessor()); | 2616 ASSERT(current_block()->HasPredecessor()); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2887 lookup->holder() != *global) { | 2879 lookup->holder() != *global) { |
2888 return kUseGeneric; | 2880 return kUseGeneric; |
2889 } | 2881 } |
2890 | 2882 |
2891 return kUseCell; | 2883 return kUseCell; |
2892 } | 2884 } |
2893 | 2885 |
2894 | 2886 |
2895 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) { | 2887 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) { |
2896 ASSERT(var->IsContextSlot()); | 2888 ASSERT(var->IsContextSlot()); |
2897 HValue* context = environment()->LookupContext(); | 2889 HInstruction* context = new(zone()) HContext; |
| 2890 AddInstruction(context); |
2898 int length = info()->scope()->ContextChainLength(var->scope()); | 2891 int length = info()->scope()->ContextChainLength(var->scope()); |
2899 while (length-- > 0) { | 2892 while (length-- > 0) { |
2900 HInstruction* context_instruction = new(zone()) HOuterContext(context); | 2893 context = new(zone()) HOuterContext(context); |
2901 AddInstruction(context_instruction); | 2894 AddInstruction(context); |
2902 context = context_instruction; | |
2903 } | 2895 } |
2904 return context; | 2896 return context; |
2905 } | 2897 } |
2906 | 2898 |
2907 | 2899 |
2908 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 2900 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
2909 ASSERT(!HasStackOverflow()); | 2901 ASSERT(!HasStackOverflow()); |
2910 ASSERT(current_block() != NULL); | 2902 ASSERT(current_block() != NULL); |
2911 ASSERT(current_block()->HasPredecessor()); | 2903 ASSERT(current_block()->HasPredecessor()); |
2912 Variable* variable = expr->AsVariable(); | 2904 Variable* variable = expr->AsVariable(); |
(...skipping 18 matching lines...) Expand all Loading... |
2931 type = kUseGeneric; | 2923 type = kUseGeneric; |
2932 } | 2924 } |
2933 | 2925 |
2934 if (type == kUseCell) { | 2926 if (type == kUseCell) { |
2935 Handle<GlobalObject> global(info()->global_object()); | 2927 Handle<GlobalObject> global(info()->global_object()); |
2936 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 2928 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
2937 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); | 2929 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); |
2938 HLoadGlobalCell* instr = new(zone()) HLoadGlobalCell(cell, check_hole); | 2930 HLoadGlobalCell* instr = new(zone()) HLoadGlobalCell(cell, check_hole); |
2939 ast_context()->ReturnInstruction(instr, expr->id()); | 2931 ast_context()->ReturnInstruction(instr, expr->id()); |
2940 } else { | 2932 } else { |
2941 HValue* context = environment()->LookupContext(); | 2933 HContext* context = new(zone()) HContext; |
| 2934 AddInstruction(context); |
2942 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 2935 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
2943 AddInstruction(global_object); | 2936 AddInstruction(global_object); |
2944 HLoadGlobalGeneric* instr = | 2937 HLoadGlobalGeneric* instr = |
2945 new(zone()) HLoadGlobalGeneric(context, | 2938 new(zone()) HLoadGlobalGeneric(context, |
2946 global_object, | 2939 global_object, |
2947 variable->name(), | 2940 variable->name(), |
2948 ast_context()->is_for_typeof()); | 2941 ast_context()->is_for_typeof()); |
2949 instr->set_position(expr->position()); | 2942 instr->set_position(expr->position()); |
2950 ASSERT(instr->HasSideEffects()); | 2943 ASSERT(instr->HasSideEffects()); |
2951 ast_context()->ReturnInstruction(instr, expr->id()); | 2944 ast_context()->ReturnInstruction(instr, expr->id()); |
(...skipping 22 matching lines...) Expand all Loading... |
2974 expr->flags(), | 2967 expr->flags(), |
2975 expr->literal_index()); | 2968 expr->literal_index()); |
2976 ast_context()->ReturnInstruction(instr, expr->id()); | 2969 ast_context()->ReturnInstruction(instr, expr->id()); |
2977 } | 2970 } |
2978 | 2971 |
2979 | 2972 |
2980 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 2973 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
2981 ASSERT(!HasStackOverflow()); | 2974 ASSERT(!HasStackOverflow()); |
2982 ASSERT(current_block() != NULL); | 2975 ASSERT(current_block() != NULL); |
2983 ASSERT(current_block()->HasPredecessor()); | 2976 ASSERT(current_block()->HasPredecessor()); |
2984 HValue* context = environment()->LookupContext(); | 2977 HContext* context = new(zone()) HContext; |
| 2978 AddInstruction(context); |
2985 HObjectLiteral* literal = | 2979 HObjectLiteral* literal = |
2986 new(zone()) HObjectLiteral(context, | 2980 new(zone()) HObjectLiteral(context, |
2987 expr->constant_properties(), | 2981 expr->constant_properties(), |
2988 expr->fast_elements(), | 2982 expr->fast_elements(), |
2989 expr->literal_index(), | 2983 expr->literal_index(), |
2990 expr->depth(), | 2984 expr->depth(), |
2991 expr->has_function()); | 2985 expr->has_function()); |
2992 // The object is expected in the bailout environment during computation | 2986 // The object is expected in the bailout environment during computation |
2993 // of the property values and is the value of the entire expression. | 2987 // of the property values and is the value of the entire expression. |
2994 PushAndAdd(literal); | 2988 PushAndAdd(literal); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3156 // enable elimination of redundant checks after the transition store. | 3150 // enable elimination of redundant checks after the transition store. |
3157 instr->SetFlag(HValue::kChangesMaps); | 3151 instr->SetFlag(HValue::kChangesMaps); |
3158 } | 3152 } |
3159 return instr; | 3153 return instr; |
3160 } | 3154 } |
3161 | 3155 |
3162 | 3156 |
3163 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object, | 3157 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object, |
3164 Handle<String> name, | 3158 Handle<String> name, |
3165 HValue* value) { | 3159 HValue* value) { |
3166 HValue* context = environment()->LookupContext(); | 3160 HContext* context = new(zone()) HContext; |
| 3161 AddInstruction(context); |
3167 return new(zone()) HStoreNamedGeneric( | 3162 return new(zone()) HStoreNamedGeneric( |
3168 context, | 3163 context, |
3169 object, | 3164 object, |
3170 name, | 3165 name, |
3171 value, | 3166 value, |
3172 function_strict_mode()); | 3167 function_strict_mode()); |
3173 } | 3168 } |
3174 | 3169 |
3175 | 3170 |
3176 HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, | 3171 HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3332 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 3327 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
3333 if (type == kUseCell) { | 3328 if (type == kUseCell) { |
3334 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); | 3329 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); |
3335 Handle<GlobalObject> global(info()->global_object()); | 3330 Handle<GlobalObject> global(info()->global_object()); |
3336 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 3331 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
3337 HInstruction* instr = new(zone()) HStoreGlobalCell(value, cell, check_hole); | 3332 HInstruction* instr = new(zone()) HStoreGlobalCell(value, cell, check_hole); |
3338 instr->set_position(position); | 3333 instr->set_position(position); |
3339 AddInstruction(instr); | 3334 AddInstruction(instr); |
3340 if (instr->HasSideEffects()) AddSimulate(ast_id); | 3335 if (instr->HasSideEffects()) AddSimulate(ast_id); |
3341 } else { | 3336 } else { |
3342 HValue* context = environment()->LookupContext(); | 3337 HContext* context = new(zone()) HContext; |
| 3338 AddInstruction(context); |
3343 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 3339 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
3344 AddInstruction(global_object); | 3340 AddInstruction(global_object); |
3345 HStoreGlobalGeneric* instr = | 3341 HStoreGlobalGeneric* instr = |
3346 new(zone()) HStoreGlobalGeneric(context, | 3342 new(zone()) HStoreGlobalGeneric(context, |
3347 global_object, | 3343 global_object, |
3348 var->name(), | 3344 var->name(), |
3349 value, | 3345 value, |
3350 function_strict_mode()); | 3346 function_strict_mode()); |
3351 instr->set_position(position); | 3347 instr->set_position(position); |
3352 AddInstruction(instr); | 3348 AddInstruction(instr); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3557 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; | 3553 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; |
3558 return new(zone()) HLoadNamedField(object, false, offset); | 3554 return new(zone()) HLoadNamedField(object, false, offset); |
3559 } | 3555 } |
3560 } | 3556 } |
3561 | 3557 |
3562 | 3558 |
3563 HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj, | 3559 HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj, |
3564 Property* expr) { | 3560 Property* expr) { |
3565 ASSERT(expr->key()->IsPropertyName()); | 3561 ASSERT(expr->key()->IsPropertyName()); |
3566 Handle<Object> name = expr->key()->AsLiteral()->handle(); | 3562 Handle<Object> name = expr->key()->AsLiteral()->handle(); |
3567 HValue* context = environment()->LookupContext(); | 3563 HContext* context = new(zone()) HContext; |
| 3564 AddInstruction(context); |
3568 return new(zone()) HLoadNamedGeneric(context, obj, name); | 3565 return new(zone()) HLoadNamedGeneric(context, obj, name); |
3569 } | 3566 } |
3570 | 3567 |
3571 | 3568 |
3572 HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj, | 3569 HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj, |
3573 Property* expr, | 3570 Property* expr, |
3574 Handle<Map> map, | 3571 Handle<Map> map, |
3575 Handle<String> name) { | 3572 Handle<String> name) { |
3576 LookupResult lookup; | 3573 LookupResult lookup; |
3577 map->LookupInDescriptors(NULL, *name, &lookup); | 3574 map->LookupInDescriptors(NULL, *name, &lookup); |
3578 if (lookup.IsProperty() && lookup.type() == FIELD) { | 3575 if (lookup.IsProperty() && lookup.type() == FIELD) { |
3579 return BuildLoadNamedField(obj, | 3576 return BuildLoadNamedField(obj, |
3580 expr, | 3577 expr, |
3581 map, | 3578 map, |
3582 &lookup, | 3579 &lookup, |
3583 true); | 3580 true); |
3584 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) { | 3581 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) { |
3585 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 3582 AddInstruction(new(zone()) HCheckNonSmi(obj)); |
3586 AddInstruction(new(zone()) HCheckMap(obj, map)); | 3583 AddInstruction(new(zone()) HCheckMap(obj, map)); |
3587 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); | 3584 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); |
3588 return new(zone()) HConstant(function, Representation::Tagged()); | 3585 return new(zone()) HConstant(function, Representation::Tagged()); |
3589 } else { | 3586 } else { |
3590 return BuildLoadNamedGeneric(obj, expr); | 3587 return BuildLoadNamedGeneric(obj, expr); |
3591 } | 3588 } |
3592 } | 3589 } |
3593 | 3590 |
3594 | 3591 |
3595 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 3592 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
3596 HValue* key) { | 3593 HValue* key) { |
3597 HValue* context = environment()->LookupContext(); | 3594 HContext* context = new(zone()) HContext; |
| 3595 AddInstruction(context); |
3598 return new(zone()) HLoadKeyedGeneric(context, object, key); | 3596 return new(zone()) HLoadKeyedGeneric(context, object, key); |
3599 } | 3597 } |
3600 | 3598 |
3601 | 3599 |
3602 HInstruction* HGraphBuilder::BuildLoadKeyedFastElement(HValue* object, | 3600 HInstruction* HGraphBuilder::BuildLoadKeyedFastElement(HValue* object, |
3603 HValue* key, | 3601 HValue* key, |
3604 Property* expr) { | 3602 Property* expr) { |
3605 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); | 3603 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); |
3606 AddInstruction(new(zone()) HCheckNonSmi(object)); | 3604 AddInstruction(new(zone()) HCheckNonSmi(object)); |
3607 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 3605 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3662 return BuildLoadKeyedFastElement(obj, key, prop); | 3660 return BuildLoadKeyedFastElement(obj, key, prop); |
3663 } | 3661 } |
3664 } | 3662 } |
3665 return BuildLoadKeyedGeneric(obj, key); | 3663 return BuildLoadKeyedGeneric(obj, key); |
3666 } | 3664 } |
3667 | 3665 |
3668 | 3666 |
3669 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, | 3667 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, |
3670 HValue* key, | 3668 HValue* key, |
3671 HValue* value) { | 3669 HValue* value) { |
3672 HValue* context = environment()->LookupContext(); | 3670 HContext* context = new(zone()) HContext; |
| 3671 AddInstruction(context); |
3673 return new(zone()) HStoreKeyedGeneric( | 3672 return new(zone()) HStoreKeyedGeneric( |
3674 context, | 3673 context, |
3675 object, | 3674 object, |
3676 key, | 3675 key, |
3677 value, | 3676 value, |
3678 function_strict_mode()); | 3677 function_strict_mode()); |
3679 } | 3678 } |
3680 | 3679 |
3681 | 3680 |
3682 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object, | 3681 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object, |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3915 set_current_block(if_false); | 3914 set_current_block(if_false); |
3916 } | 3915 } |
3917 } | 3916 } |
3918 | 3917 |
3919 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 3918 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
3920 // know about and do not want to handle ones we've never seen. Otherwise | 3919 // know about and do not want to handle ones we've never seen. Otherwise |
3921 // use a generic IC. | 3920 // use a generic IC. |
3922 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { | 3921 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { |
3923 current_block()->FinishExitWithDeoptimization(); | 3922 current_block()->FinishExitWithDeoptimization(); |
3924 } else { | 3923 } else { |
3925 HValue* context = environment()->LookupContext(); | 3924 HContext* context = new(zone()) HContext; |
| 3925 AddInstruction(context); |
3926 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); | 3926 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); |
3927 call->set_position(expr->position()); | 3927 call->set_position(expr->position()); |
3928 PreProcessCall(call); | 3928 PreProcessCall(call); |
3929 | 3929 |
3930 if (join != NULL) { | 3930 if (join != NULL) { |
3931 AddInstruction(call); | 3931 AddInstruction(call); |
3932 if (!ast_context()->IsEffect()) Push(call); | 3932 if (!ast_context()->IsEffect()) Push(call); |
3933 current_block()->Goto(join); | 3933 current_block()->Goto(join); |
3934 } else { | 3934 } else { |
3935 ast_context()->ReturnInstruction(call, expr->id()); | 3935 ast_context()->ReturnInstruction(call, expr->id()); |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4342 | 4342 |
4343 CHECK_ALIVE(VisitForValue(prop->key())); | 4343 CHECK_ALIVE(VisitForValue(prop->key())); |
4344 // Push receiver and key like the non-optimized code generator expects it. | 4344 // Push receiver and key like the non-optimized code generator expects it. |
4345 HValue* key = Pop(); | 4345 HValue* key = Pop(); |
4346 HValue* receiver = Pop(); | 4346 HValue* receiver = Pop(); |
4347 Push(key); | 4347 Push(key); |
4348 Push(receiver); | 4348 Push(receiver); |
4349 | 4349 |
4350 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4350 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
4351 | 4351 |
4352 HValue* context = environment()->LookupContext(); | 4352 HContext* context = new(zone()) HContext; |
| 4353 AddInstruction(context); |
4353 call = PreProcessCall( | 4354 call = PreProcessCall( |
4354 new(zone()) HCallKeyed(context, key, argument_count)); | 4355 new(zone()) HCallKeyed(context, key, argument_count)); |
4355 call->set_position(expr->position()); | 4356 call->set_position(expr->position()); |
4356 Drop(1); // Key. | 4357 Drop(1); // Key. |
4357 ast_context()->ReturnInstruction(call, expr->id()); | 4358 ast_context()->ReturnInstruction(call, expr->id()); |
4358 return; | 4359 return; |
4359 } | 4360 } |
4360 | 4361 |
4361 // Named function call. | 4362 // Named function call. |
4362 expr->RecordTypeFeedback(oracle()); | 4363 expr->RecordTypeFeedback(oracle()); |
(...skipping 18 matching lines...) Expand all Loading... |
4381 receiver_map, | 4382 receiver_map, |
4382 expr->check_type())) { | 4383 expr->check_type())) { |
4383 return; | 4384 return; |
4384 } | 4385 } |
4385 | 4386 |
4386 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) || | 4387 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) || |
4387 expr->check_type() != RECEIVER_MAP_CHECK) { | 4388 expr->check_type() != RECEIVER_MAP_CHECK) { |
4388 // When the target has a custom call IC generator, use the IC, | 4389 // When the target has a custom call IC generator, use the IC, |
4389 // because it is likely to generate better code. Also use the IC | 4390 // because it is likely to generate better code. Also use the IC |
4390 // when a primitive receiver check is required. | 4391 // when a primitive receiver check is required. |
4391 HValue* context = environment()->LookupContext(); | 4392 HContext* context = new(zone()) HContext; |
| 4393 AddInstruction(context); |
4392 call = PreProcessCall( | 4394 call = PreProcessCall( |
4393 new(zone()) HCallNamed(context, name, argument_count)); | 4395 new(zone()) HCallNamed(context, name, argument_count)); |
4394 } else { | 4396 } else { |
4395 AddCheckConstantFunction(expr, receiver, receiver_map, true); | 4397 AddCheckConstantFunction(expr, receiver, receiver_map, true); |
4396 | 4398 |
4397 if (TryInline(expr)) return; | 4399 if (TryInline(expr)) return; |
4398 call = PreProcessCall( | 4400 call = PreProcessCall( |
4399 new(zone()) HCallConstantFunction(expr->target(), | 4401 new(zone()) HCallConstantFunction(expr->target(), |
4400 argument_count)); | 4402 argument_count)); |
4401 } | 4403 } |
4402 } else if (types != NULL && types->length() > 1) { | 4404 } else if (types != NULL && types->length() > 1) { |
4403 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); | 4405 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); |
4404 HandlePolymorphicCallNamed(expr, receiver, types, name); | 4406 HandlePolymorphicCallNamed(expr, receiver, types, name); |
4405 return; | 4407 return; |
4406 | 4408 |
4407 } else { | 4409 } else { |
4408 HValue* context = environment()->LookupContext(); | 4410 HContext* context = new(zone()) HContext; |
| 4411 AddInstruction(context); |
4409 call = PreProcessCall( | 4412 call = PreProcessCall( |
4410 new(zone()) HCallNamed(context, name, argument_count)); | 4413 new(zone()) HCallNamed(context, name, argument_count)); |
4411 } | 4414 } |
4412 | 4415 |
4413 } else { | 4416 } else { |
4414 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); | 4417 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
4415 bool global_call = (var != NULL) && var->is_global() && !var->is_this(); | 4418 bool global_call = (var != NULL) && var->is_global() && !var->is_this(); |
4416 | 4419 |
4417 if (!global_call) { | 4420 if (!global_call) { |
4418 ++argument_count; | 4421 ++argument_count; |
4419 CHECK_ALIVE(VisitForValue(expr->expression())); | 4422 CHECK_ALIVE(VisitForValue(expr->expression())); |
4420 } | 4423 } |
4421 | 4424 |
4422 if (global_call) { | 4425 if (global_call) { |
4423 bool known_global_function = false; | 4426 bool known_global_function = false; |
4424 // If there is a global property cell for the name at compile time and | 4427 // If there is a global property cell for the name at compile time and |
4425 // access check is not enabled we assume that the function will not change | 4428 // access check is not enabled we assume that the function will not change |
4426 // and generate optimized code for calling the function. | 4429 // and generate optimized code for calling the function. |
4427 LookupResult lookup; | 4430 LookupResult lookup; |
4428 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); | 4431 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); |
4429 if (type == kUseCell && | 4432 if (type == kUseCell && |
4430 !info()->global_object()->IsAccessCheckNeeded()) { | 4433 !info()->global_object()->IsAccessCheckNeeded()) { |
4431 Handle<GlobalObject> global(info()->global_object()); | 4434 Handle<GlobalObject> global(info()->global_object()); |
4432 known_global_function = expr->ComputeGlobalTarget(global, &lookup); | 4435 known_global_function = expr->ComputeGlobalTarget(global, &lookup); |
4433 } | 4436 } |
4434 if (known_global_function) { | 4437 if (known_global_function) { |
4435 // Push the global object instead of the global receiver because | 4438 // Push the global object instead of the global receiver because |
4436 // code generated by the full code generator expects it. | 4439 // code generated by the full code generator expects it. |
4437 HValue* context = environment()->LookupContext(); | 4440 HContext* context = new(zone()) HContext; |
4438 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 4441 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 4442 AddInstruction(context); |
4439 PushAndAdd(global_object); | 4443 PushAndAdd(global_object); |
4440 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4444 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
4441 | 4445 |
4442 CHECK_ALIVE(VisitForValue(expr->expression())); | 4446 CHECK_ALIVE(VisitForValue(expr->expression())); |
4443 HValue* function = Pop(); | 4447 HValue* function = Pop(); |
4444 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); | 4448 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); |
4445 | 4449 |
4446 // Replace the global object with the global receiver. | 4450 // Replace the global object with the global receiver. |
4447 HGlobalReceiver* global_receiver = | 4451 HGlobalReceiver* global_receiver = |
4448 new(zone()) HGlobalReceiver(global_object); | 4452 new(zone()) HGlobalReceiver(global_object); |
4449 // Index of the receiver from the top of the expression stack. | 4453 // Index of the receiver from the top of the expression stack. |
4450 const int receiver_index = argument_count - 1; | 4454 const int receiver_index = argument_count - 1; |
4451 AddInstruction(global_receiver); | 4455 AddInstruction(global_receiver); |
4452 ASSERT(environment()->ExpressionStackAt(receiver_index)-> | 4456 ASSERT(environment()->ExpressionStackAt(receiver_index)-> |
4453 IsGlobalObject()); | 4457 IsGlobalObject()); |
4454 environment()->SetExpressionStackAt(receiver_index, global_receiver); | 4458 environment()->SetExpressionStackAt(receiver_index, global_receiver); |
4455 | 4459 |
4456 if (TryInline(expr)) return; | 4460 if (TryInline(expr)) return; |
4457 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), | 4461 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), |
4458 argument_count)); | 4462 argument_count)); |
4459 } else { | 4463 } else { |
4460 HValue* context = environment()->LookupContext(); | 4464 HContext* context = new(zone()) HContext; |
| 4465 AddInstruction(context); |
4461 PushAndAdd(new(zone()) HGlobalObject(context)); | 4466 PushAndAdd(new(zone()) HGlobalObject(context)); |
4462 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4467 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
4463 | 4468 |
4464 call = PreProcessCall(new(zone()) HCallGlobal(context, | 4469 call = PreProcessCall(new(zone()) HCallGlobal(context, |
4465 var->name(), | 4470 var->name(), |
4466 argument_count)); | 4471 argument_count)); |
4467 } | 4472 } |
4468 | 4473 |
4469 } else { | 4474 } else { |
4470 HValue* context = environment()->LookupContext(); | 4475 HContext* context = new(zone()) HContext; |
4471 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 4476 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 4477 AddInstruction(context); |
4472 AddInstruction(global_object); | 4478 AddInstruction(global_object); |
4473 PushAndAdd(new(zone()) HGlobalReceiver(global_object)); | 4479 PushAndAdd(new(zone()) HGlobalReceiver(global_object)); |
4474 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4480 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
4475 | 4481 |
4476 call = PreProcessCall(new(zone()) HCallFunction(context, argument_count)); | 4482 call = PreProcessCall(new(zone()) HCallFunction(context, argument_count)); |
4477 } | 4483 } |
4478 } | 4484 } |
4479 | 4485 |
4480 call->set_position(expr->position()); | 4486 call->set_position(expr->position()); |
4481 ast_context()->ReturnInstruction(call, expr->id()); | 4487 ast_context()->ReturnInstruction(call, expr->id()); |
4482 } | 4488 } |
4483 | 4489 |
4484 | 4490 |
4485 void HGraphBuilder::VisitCallNew(CallNew* expr) { | 4491 void HGraphBuilder::VisitCallNew(CallNew* expr) { |
4486 ASSERT(!HasStackOverflow()); | 4492 ASSERT(!HasStackOverflow()); |
4487 ASSERT(current_block() != NULL); | 4493 ASSERT(current_block() != NULL); |
4488 ASSERT(current_block()->HasPredecessor()); | 4494 ASSERT(current_block()->HasPredecessor()); |
4489 // The constructor function is also used as the receiver argument to the | 4495 // The constructor function is also used as the receiver argument to the |
4490 // JS construct call builtin. | 4496 // JS construct call builtin. |
4491 CHECK_ALIVE(VisitForValue(expr->expression())); | 4497 CHECK_ALIVE(VisitForValue(expr->expression())); |
4492 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4498 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
4493 | 4499 |
4494 HValue* context = environment()->LookupContext(); | 4500 HContext* context = new(zone()) HContext; |
| 4501 AddInstruction(context); |
4495 | 4502 |
4496 // The constructor is both an operand to the instruction and an argument | 4503 // The constructor is both an operand to the instruction and an argument |
4497 // to the construct call. | 4504 // to the construct call. |
4498 int arg_count = expr->arguments()->length() + 1; // Plus constructor. | 4505 int arg_count = expr->arguments()->length() + 1; // Plus constructor. |
4499 HValue* constructor = environment()->ExpressionStackAt(arg_count - 1); | 4506 HValue* constructor = environment()->ExpressionStackAt(arg_count - 1); |
4500 HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count); | 4507 HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count); |
4501 call->set_position(expr->position()); | 4508 call->set_position(expr->position()); |
4502 PreProcessCall(call); | 4509 PreProcessCall(call); |
4503 ast_context()->ReturnInstruction(call, expr->id()); | 4510 ast_context()->ReturnInstruction(call, expr->id()); |
4504 } | 4511 } |
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5107 // change and thus prefer the general IC code. | 5114 // change and thus prefer the general IC code. |
5108 if (!isolate()->heap()->InNewSpace(*candidate)) { | 5115 if (!isolate()->heap()->InNewSpace(*candidate)) { |
5109 target = candidate; | 5116 target = candidate; |
5110 } | 5117 } |
5111 } | 5118 } |
5112 } | 5119 } |
5113 | 5120 |
5114 // If the target is not null we have found a known global function that is | 5121 // If the target is not null we have found a known global function that is |
5115 // assumed to stay the same for this instanceof. | 5122 // assumed to stay the same for this instanceof. |
5116 if (target.is_null()) { | 5123 if (target.is_null()) { |
5117 HValue* context = environment()->LookupContext(); | 5124 HContext* context = new(zone()) HContext; |
| 5125 AddInstruction(context); |
5118 instr = new(zone()) HInstanceOf(context, left, right); | 5126 instr = new(zone()) HInstanceOf(context, left, right); |
5119 } else { | 5127 } else { |
5120 AddInstruction(new(zone()) HCheckFunction(right, target)); | 5128 AddInstruction(new(zone()) HCheckFunction(right, target)); |
5121 instr = new(zone()) HInstanceOfKnownGlobal(left, target); | 5129 instr = new(zone()) HInstanceOfKnownGlobal(left, target); |
5122 } | 5130 } |
5123 } else if (op == Token::IN) { | 5131 } else if (op == Token::IN) { |
5124 instr = new(zone()) HIn(left, right); | 5132 instr = new(zone()) HIn(left, right); |
5125 } else if (type_info.IsNonPrimitive()) { | 5133 } else if (type_info.IsNonPrimitive()) { |
5126 switch (op) { | 5134 switch (op) { |
5127 case Token::EQ: | 5135 case Token::EQ: |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5383 // Fast support for Math.random(). | 5391 // Fast support for Math.random(). |
5384 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { | 5392 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { |
5385 return Bailout("inlined runtime function: RandomHeapNumber"); | 5393 return Bailout("inlined runtime function: RandomHeapNumber"); |
5386 } | 5394 } |
5387 | 5395 |
5388 | 5396 |
5389 // Fast support for StringAdd. | 5397 // Fast support for StringAdd. |
5390 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) { | 5398 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) { |
5391 ASSERT_EQ(2, call->arguments()->length()); | 5399 ASSERT_EQ(2, call->arguments()->length()); |
5392 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5400 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5393 HValue* context = environment()->LookupContext(); | 5401 HContext* context = new(zone()) HContext; |
| 5402 AddInstruction(context); |
5394 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2); | 5403 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2); |
5395 Drop(2); | 5404 Drop(2); |
5396 ast_context()->ReturnInstruction(result, call->id()); | 5405 ast_context()->ReturnInstruction(result, call->id()); |
5397 } | 5406 } |
5398 | 5407 |
5399 | 5408 |
5400 // Fast support for SubString. | 5409 // Fast support for SubString. |
5401 void HGraphBuilder::GenerateSubString(CallRuntime* call) { | 5410 void HGraphBuilder::GenerateSubString(CallRuntime* call) { |
5402 ASSERT_EQ(3, call->arguments()->length()); | 5411 ASSERT_EQ(3, call->arguments()->length()); |
5403 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5412 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5404 HValue* context = environment()->LookupContext(); | 5413 HContext* context = new(zone()) HContext; |
| 5414 AddInstruction(context); |
5405 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); | 5415 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); |
5406 Drop(3); | 5416 Drop(3); |
5407 ast_context()->ReturnInstruction(result, call->id()); | 5417 ast_context()->ReturnInstruction(result, call->id()); |
5408 } | 5418 } |
5409 | 5419 |
5410 | 5420 |
5411 // Fast support for StringCompare. | 5421 // Fast support for StringCompare. |
5412 void HGraphBuilder::GenerateStringCompare(CallRuntime* call) { | 5422 void HGraphBuilder::GenerateStringCompare(CallRuntime* call) { |
5413 ASSERT_EQ(2, call->arguments()->length()); | 5423 ASSERT_EQ(2, call->arguments()->length()); |
5414 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5424 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5415 HValue* context = environment()->LookupContext(); | 5425 HContext* context = new(zone()) HContext; |
| 5426 AddInstruction(context); |
5416 HCallStub* result = | 5427 HCallStub* result = |
5417 new(zone()) HCallStub(context, CodeStub::StringCompare, 2); | 5428 new(zone()) HCallStub(context, CodeStub::StringCompare, 2); |
5418 Drop(2); | 5429 Drop(2); |
5419 ast_context()->ReturnInstruction(result, call->id()); | 5430 ast_context()->ReturnInstruction(result, call->id()); |
5420 } | 5431 } |
5421 | 5432 |
5422 | 5433 |
5423 // Support for direct calls from JavaScript to native RegExp code. | 5434 // Support for direct calls from JavaScript to native RegExp code. |
5424 void HGraphBuilder::GenerateRegExpExec(CallRuntime* call) { | 5435 void HGraphBuilder::GenerateRegExpExec(CallRuntime* call) { |
5425 ASSERT_EQ(4, call->arguments()->length()); | 5436 ASSERT_EQ(4, call->arguments()->length()); |
5426 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5437 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5427 HValue* context = environment()->LookupContext(); | 5438 HContext* context = new(zone()) HContext; |
| 5439 AddInstruction(context); |
5428 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4); | 5440 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4); |
5429 Drop(4); | 5441 Drop(4); |
5430 ast_context()->ReturnInstruction(result, call->id()); | 5442 ast_context()->ReturnInstruction(result, call->id()); |
5431 } | 5443 } |
5432 | 5444 |
5433 | 5445 |
5434 // Construct a RegExp exec result with two in-object properties. | 5446 // Construct a RegExp exec result with two in-object properties. |
5435 void HGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { | 5447 void HGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { |
5436 ASSERT_EQ(3, call->arguments()->length()); | 5448 ASSERT_EQ(3, call->arguments()->length()); |
5437 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5449 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5438 HValue* context = environment()->LookupContext(); | 5450 HContext* context = new(zone()) HContext; |
| 5451 AddInstruction(context); |
5439 HCallStub* result = | 5452 HCallStub* result = |
5440 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); | 5453 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); |
5441 Drop(3); | 5454 Drop(3); |
5442 ast_context()->ReturnInstruction(result, call->id()); | 5455 ast_context()->ReturnInstruction(result, call->id()); |
5443 } | 5456 } |
5444 | 5457 |
5445 | 5458 |
5446 // Support for fast native caches. | 5459 // Support for fast native caches. |
5447 void HGraphBuilder::GenerateGetFromCache(CallRuntime* call) { | 5460 void HGraphBuilder::GenerateGetFromCache(CallRuntime* call) { |
5448 return Bailout("inlined runtime function: GetFromCache"); | 5461 return Bailout("inlined runtime function: GetFromCache"); |
5449 } | 5462 } |
5450 | 5463 |
5451 | 5464 |
5452 // Fast support for number to string. | 5465 // Fast support for number to string. |
5453 void HGraphBuilder::GenerateNumberToString(CallRuntime* call) { | 5466 void HGraphBuilder::GenerateNumberToString(CallRuntime* call) { |
5454 ASSERT_EQ(1, call->arguments()->length()); | 5467 ASSERT_EQ(1, call->arguments()->length()); |
5455 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5468 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5456 HValue* context = environment()->LookupContext(); | 5469 HContext* context = new(zone()) HContext; |
| 5470 AddInstruction(context); |
5457 HCallStub* result = | 5471 HCallStub* result = |
5458 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); | 5472 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); |
5459 Drop(1); | 5473 Drop(1); |
5460 ast_context()->ReturnInstruction(result, call->id()); | 5474 ast_context()->ReturnInstruction(result, call->id()); |
5461 } | 5475 } |
5462 | 5476 |
5463 | 5477 |
5464 // Fast swapping of elements. Takes three expressions, the object and two | 5478 // Fast swapping of elements. Takes three expressions, the object and two |
5465 // indices. This should only be used if the indices are known to be | 5479 // indices. This should only be used if the indices are known to be |
5466 // non-negative and within bounds of the elements array at the call site. | 5480 // non-negative and within bounds of the elements array at the call site. |
5467 void HGraphBuilder::GenerateSwapElements(CallRuntime* call) { | 5481 void HGraphBuilder::GenerateSwapElements(CallRuntime* call) { |
5468 return Bailout("inlined runtime function: SwapElements"); | 5482 return Bailout("inlined runtime function: SwapElements"); |
5469 } | 5483 } |
5470 | 5484 |
5471 | 5485 |
5472 // Fast call for custom callbacks. | 5486 // Fast call for custom callbacks. |
5473 void HGraphBuilder::GenerateCallFunction(CallRuntime* call) { | 5487 void HGraphBuilder::GenerateCallFunction(CallRuntime* call) { |
5474 // 1 ~ The function to call is not itself an argument to the call. | 5488 // 1 ~ The function to call is not itself an argument to the call. |
5475 int arg_count = call->arguments()->length() - 1; | 5489 int arg_count = call->arguments()->length() - 1; |
5476 ASSERT(arg_count >= 1); // There's always at least a receiver. | 5490 ASSERT(arg_count >= 1); // There's always at least a receiver. |
5477 | 5491 |
5478 for (int i = 0; i < arg_count; ++i) { | 5492 for (int i = 0; i < arg_count; ++i) { |
5479 CHECK_ALIVE(VisitArgument(call->arguments()->at(i))); | 5493 CHECK_ALIVE(VisitArgument(call->arguments()->at(i))); |
5480 } | 5494 } |
5481 CHECK_ALIVE(VisitForValue(call->arguments()->last())); | 5495 CHECK_ALIVE(VisitForValue(call->arguments()->last())); |
5482 HValue* function = Pop(); | 5496 HValue* function = Pop(); |
5483 HValue* context = environment()->LookupContext(); | 5497 HContext* context = new HContext; |
| 5498 AddInstruction(context); |
5484 HInvokeFunction* result = | 5499 HInvokeFunction* result = |
5485 new(zone()) HInvokeFunction(context, function, arg_count); | 5500 new(zone()) HInvokeFunction(context, function, arg_count); |
5486 Drop(arg_count); | 5501 Drop(arg_count); |
5487 ast_context()->ReturnInstruction(result, call->id()); | 5502 ast_context()->ReturnInstruction(result, call->id()); |
5488 } | 5503 } |
5489 | 5504 |
5490 | 5505 |
5491 // Fast call to math functions. | 5506 // Fast call to math functions. |
5492 void HGraphBuilder::GenerateMathPow(CallRuntime* call) { | 5507 void HGraphBuilder::GenerateMathPow(CallRuntime* call) { |
5493 ASSERT_EQ(2, call->arguments()->length()); | 5508 ASSERT_EQ(2, call->arguments()->length()); |
5494 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 5509 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
5495 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 5510 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
5496 HValue* right = Pop(); | 5511 HValue* right = Pop(); |
5497 HValue* left = Pop(); | 5512 HValue* left = Pop(); |
5498 HPower* result = new(zone()) HPower(left, right); | 5513 HPower* result = new(zone()) HPower(left, right); |
5499 ast_context()->ReturnInstruction(result, call->id()); | 5514 ast_context()->ReturnInstruction(result, call->id()); |
5500 } | 5515 } |
5501 | 5516 |
5502 | 5517 |
5503 void HGraphBuilder::GenerateMathSin(CallRuntime* call) { | 5518 void HGraphBuilder::GenerateMathSin(CallRuntime* call) { |
5504 ASSERT_EQ(1, call->arguments()->length()); | 5519 ASSERT_EQ(1, call->arguments()->length()); |
5505 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5520 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5506 HValue* context = environment()->LookupContext(); | 5521 HContext* context = new(zone()) HContext; |
| 5522 AddInstruction(context); |
5507 HCallStub* result = | 5523 HCallStub* result = |
5508 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | 5524 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
5509 result->set_transcendental_type(TranscendentalCache::SIN); | 5525 result->set_transcendental_type(TranscendentalCache::SIN); |
5510 Drop(1); | 5526 Drop(1); |
5511 ast_context()->ReturnInstruction(result, call->id()); | 5527 ast_context()->ReturnInstruction(result, call->id()); |
5512 } | 5528 } |
5513 | 5529 |
5514 | 5530 |
5515 void HGraphBuilder::GenerateMathCos(CallRuntime* call) { | 5531 void HGraphBuilder::GenerateMathCos(CallRuntime* call) { |
5516 ASSERT_EQ(1, call->arguments()->length()); | 5532 ASSERT_EQ(1, call->arguments()->length()); |
5517 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5533 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5518 HValue* context = environment()->LookupContext(); | 5534 HContext* context = new(zone()) HContext; |
| 5535 AddInstruction(context); |
5519 HCallStub* result = | 5536 HCallStub* result = |
5520 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | 5537 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
5521 result->set_transcendental_type(TranscendentalCache::COS); | 5538 result->set_transcendental_type(TranscendentalCache::COS); |
5522 Drop(1); | 5539 Drop(1); |
5523 ast_context()->ReturnInstruction(result, call->id()); | 5540 ast_context()->ReturnInstruction(result, call->id()); |
5524 } | 5541 } |
5525 | 5542 |
5526 | 5543 |
5527 void HGraphBuilder::GenerateMathLog(CallRuntime* call) { | 5544 void HGraphBuilder::GenerateMathLog(CallRuntime* call) { |
5528 ASSERT_EQ(1, call->arguments()->length()); | 5545 ASSERT_EQ(1, call->arguments()->length()); |
5529 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5546 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5530 HValue* context = environment()->LookupContext(); | 5547 HContext* context = new(zone()) HContext; |
| 5548 AddInstruction(context); |
5531 HCallStub* result = | 5549 HCallStub* result = |
5532 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | 5550 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
5533 result->set_transcendental_type(TranscendentalCache::LOG); | 5551 result->set_transcendental_type(TranscendentalCache::LOG); |
5534 Drop(1); | 5552 Drop(1); |
5535 ast_context()->ReturnInstruction(result, call->id()); | 5553 ast_context()->ReturnInstruction(result, call->id()); |
5536 } | 5554 } |
5537 | 5555 |
5538 | 5556 |
5539 void HGraphBuilder::GenerateMathSqrt(CallRuntime* call) { | 5557 void HGraphBuilder::GenerateMathSqrt(CallRuntime* call) { |
5540 return Bailout("inlined runtime function: MathSqrt"); | 5558 return Bailout("inlined runtime function: MathSqrt"); |
(...skipping 24 matching lines...) Expand all Loading... |
5565 #undef CHECK_ALIVE | 5583 #undef CHECK_ALIVE |
5566 | 5584 |
5567 | 5585 |
5568 HEnvironment::HEnvironment(HEnvironment* outer, | 5586 HEnvironment::HEnvironment(HEnvironment* outer, |
5569 Scope* scope, | 5587 Scope* scope, |
5570 Handle<JSFunction> closure) | 5588 Handle<JSFunction> closure) |
5571 : closure_(closure), | 5589 : closure_(closure), |
5572 values_(0), | 5590 values_(0), |
5573 assigned_variables_(4), | 5591 assigned_variables_(4), |
5574 parameter_count_(0), | 5592 parameter_count_(0), |
5575 specials_count_(1), | |
5576 local_count_(0), | 5593 local_count_(0), |
5577 outer_(outer), | 5594 outer_(outer), |
5578 pop_count_(0), | 5595 pop_count_(0), |
5579 push_count_(0), | 5596 push_count_(0), |
5580 ast_id_(AstNode::kNoNumber) { | 5597 ast_id_(AstNode::kNoNumber) { |
5581 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); | 5598 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); |
5582 } | 5599 } |
5583 | 5600 |
5584 | 5601 |
5585 HEnvironment::HEnvironment(const HEnvironment* other) | 5602 HEnvironment::HEnvironment(const HEnvironment* other) |
5586 : values_(0), | 5603 : values_(0), |
5587 assigned_variables_(0), | 5604 assigned_variables_(0), |
5588 parameter_count_(0), | 5605 parameter_count_(0), |
5589 specials_count_(1), | |
5590 local_count_(0), | 5606 local_count_(0), |
5591 outer_(NULL), | 5607 outer_(NULL), |
5592 pop_count_(0), | 5608 pop_count_(0), |
5593 push_count_(0), | 5609 push_count_(0), |
5594 ast_id_(other->ast_id()) { | 5610 ast_id_(other->ast_id()) { |
5595 Initialize(other); | 5611 Initialize(other); |
5596 } | 5612 } |
5597 | 5613 |
5598 | 5614 |
5599 void HEnvironment::Initialize(int parameter_count, | 5615 void HEnvironment::Initialize(int parameter_count, |
5600 int local_count, | 5616 int local_count, |
5601 int stack_height) { | 5617 int stack_height) { |
5602 parameter_count_ = parameter_count; | 5618 parameter_count_ = parameter_count; |
5603 local_count_ = local_count; | 5619 local_count_ = local_count; |
5604 | 5620 |
5605 // Avoid reallocating the temporaries' backing store on the first Push. | 5621 // Avoid reallocating the temporaries' backing store on the first Push. |
5606 int total = parameter_count + specials_count_ + local_count + stack_height; | 5622 int total = parameter_count + local_count + stack_height; |
5607 values_.Initialize(total + 4); | 5623 values_.Initialize(total + 4); |
5608 for (int i = 0; i < total; ++i) values_.Add(NULL); | 5624 for (int i = 0; i < total; ++i) values_.Add(NULL); |
5609 } | 5625 } |
5610 | 5626 |
5611 | 5627 |
5612 void HEnvironment::Initialize(const HEnvironment* other) { | 5628 void HEnvironment::Initialize(const HEnvironment* other) { |
5613 closure_ = other->closure(); | 5629 closure_ = other->closure(); |
5614 values_.AddAll(other->values_); | 5630 values_.AddAll(other->values_); |
5615 assigned_variables_.AddAll(other->assigned_variables_); | 5631 assigned_variables_.AddAll(other->assigned_variables_); |
5616 parameter_count_ = other->parameter_count_; | 5632 parameter_count_ = other->parameter_count_; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5655 void HEnvironment::Bind(int index, HValue* value) { | 5671 void HEnvironment::Bind(int index, HValue* value) { |
5656 ASSERT(value != NULL); | 5672 ASSERT(value != NULL); |
5657 if (!assigned_variables_.Contains(index)) { | 5673 if (!assigned_variables_.Contains(index)) { |
5658 assigned_variables_.Add(index); | 5674 assigned_variables_.Add(index); |
5659 } | 5675 } |
5660 values_[index] = value; | 5676 values_[index] = value; |
5661 } | 5677 } |
5662 | 5678 |
5663 | 5679 |
5664 bool HEnvironment::HasExpressionAt(int index) const { | 5680 bool HEnvironment::HasExpressionAt(int index) const { |
5665 return index >= parameter_count_ + specials_count_ + local_count_; | 5681 return index >= parameter_count_ + local_count_; |
5666 } | 5682 } |
5667 | 5683 |
5668 | 5684 |
5669 bool HEnvironment::ExpressionStackIsEmpty() const { | 5685 bool HEnvironment::ExpressionStackIsEmpty() const { |
5670 int first_expression = parameter_count() + specials_count() + local_count(); | 5686 int first_expression = parameter_count() + local_count(); |
5671 ASSERT(length() >= first_expression); | 5687 ASSERT(length() >= first_expression); |
5672 return length() == first_expression; | 5688 return length() == first_expression; |
5673 } | 5689 } |
5674 | 5690 |
5675 | 5691 |
5676 void HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) { | 5692 void HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) { |
5677 int count = index_from_top + 1; | 5693 int count = index_from_top + 1; |
5678 int index = values_.length() - count; | 5694 int index = values_.length() - count; |
5679 ASSERT(HasExpressionAt(index)); | 5695 ASSERT(HasExpressionAt(index)); |
5680 // The push count must include at least the element in question or else | 5696 // The push count must include at least the element in question or else |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5738 HValue* push = ExpressionStackAt(arity - i); | 5754 HValue* push = ExpressionStackAt(arity - i); |
5739 inner->SetValueAt(i, push); | 5755 inner->SetValueAt(i, push); |
5740 } | 5756 } |
5741 } else { | 5757 } else { |
5742 ASSERT(compilation_phase == LITHIUM); | 5758 ASSERT(compilation_phase == LITHIUM); |
5743 for (int i = 0; i <= arity; ++i) { // Include receiver. | 5759 for (int i = 0; i <= arity; ++i) { // Include receiver. |
5744 HValue* push = ExpressionStackAt(arity - i); | 5760 HValue* push = ExpressionStackAt(arity - i); |
5745 inner->SetValueAt(i, push); | 5761 inner->SetValueAt(i, push); |
5746 } | 5762 } |
5747 } | 5763 } |
5748 inner->SetValueAt(arity + 1, outer->LookupContext()); | 5764 |
5749 for (int i = arity + 2; i < inner->length(); ++i) { | 5765 // Initialize the stack-allocated locals to undefined. |
5750 inner->SetValueAt(i, undefined); | 5766 int local_base = arity + 1; |
| 5767 int local_count = function->scope()->num_stack_slots(); |
| 5768 for (int i = 0; i < local_count; ++i) { |
| 5769 inner->SetValueAt(local_base + i, undefined); |
5751 } | 5770 } |
5752 | 5771 |
5753 inner->set_ast_id(AstNode::kFunctionEntryId); | 5772 inner->set_ast_id(AstNode::kFunctionEntryId); |
5754 return inner; | 5773 return inner; |
5755 } | 5774 } |
5756 | 5775 |
5757 | 5776 |
5758 void HEnvironment::PrintTo(StringStream* stream) { | 5777 void HEnvironment::PrintTo(StringStream* stream) { |
5759 for (int i = 0; i < length(); i++) { | 5778 for (int i = 0; i < length(); i++) { |
5760 if (i == 0) stream->Add("parameters\n"); | 5779 if (i == 0) stream->Add("parameters\n"); |
5761 if (i == parameter_count()) stream->Add("specials\n"); | 5780 if (i == parameter_count()) stream->Add("locals\n"); |
5762 if (i == parameter_count() + specials_count()) stream->Add("locals\n"); | 5781 if (i == parameter_count() + local_count()) stream->Add("expressions"); |
5763 if (i == parameter_count() + specials_count() + local_count()) { | |
5764 stream->Add("expressions"); | |
5765 } | |
5766 HValue* val = values_.at(i); | 5782 HValue* val = values_.at(i); |
5767 stream->Add("%d: ", i); | 5783 stream->Add("%d: ", i); |
5768 if (val != NULL) { | 5784 if (val != NULL) { |
5769 val->PrintNameTo(stream); | 5785 val->PrintNameTo(stream); |
5770 } else { | 5786 } else { |
5771 stream->Add("NULL"); | 5787 stream->Add("NULL"); |
5772 } | 5788 } |
5773 stream->Add("\n"); | 5789 stream->Add("\n"); |
5774 } | 5790 } |
5775 } | 5791 } |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6081 } | 6097 } |
6082 } | 6098 } |
6083 | 6099 |
6084 #ifdef DEBUG | 6100 #ifdef DEBUG |
6085 if (graph_ != NULL) graph_->Verify(); | 6101 if (graph_ != NULL) graph_->Verify(); |
6086 if (allocator_ != NULL) allocator_->Verify(); | 6102 if (allocator_ != NULL) allocator_->Verify(); |
6087 #endif | 6103 #endif |
6088 } | 6104 } |
6089 | 6105 |
6090 } } // namespace v8::internal | 6106 } } // namespace v8::internal |
OLD | NEW |