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

Powered by Google App Engine
This is Rietveld 408576698