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