Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/hydrogen.cc

Issue 6929066: First step in letting Crankshaft inline functions with a different context. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698