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

Side by Side Diff: src/hydrogen.cc

Issue 10702109: Slightly generalize AddCheckConstantFunction. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 5 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
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 6266 matching lines...) Expand 10 before | Expand all | Expand 10 after
6277 Drop(1); 6277 Drop(1);
6278 } 6278 }
6279 } 6279 }
6280 return ast_context()->ReturnValue(load); 6280 return ast_context()->ReturnValue(load);
6281 } 6281 }
6282 instr->set_position(expr->position()); 6282 instr->set_position(expr->position());
6283 return ast_context()->ReturnInstruction(instr, expr->id()); 6283 return ast_context()->ReturnInstruction(instr, expr->id());
6284 } 6284 }
6285 6285
6286 6286
6287 void HGraphBuilder::AddCheckConstantFunction(Call* expr, 6287 void HGraphBuilder::AddCheckConstantFunction(Handle<JSObject> holder,
6288 HValue* receiver, 6288 HValue* receiver,
6289 Handle<Map> receiver_map, 6289 Handle<Map> receiver_map,
6290 bool smi_and_map_check) { 6290 bool smi_and_map_check) {
6291 // Constant functions have the nice property that the map will change if they 6291 // Constant functions have the nice property that the map will change if they
6292 // are overwritten. Therefore it is enough to check the map of the holder and 6292 // are overwritten. Therefore it is enough to check the map of the holder and
6293 // its prototypes. 6293 // its prototypes.
6294 if (smi_and_map_check) { 6294 if (smi_and_map_check) {
6295 AddInstruction(new(zone()) HCheckNonSmi(receiver)); 6295 AddInstruction(new(zone()) HCheckNonSmi(receiver));
6296 AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map, 6296 AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map,
6297 zone())); 6297 zone()));
6298 } 6298 }
6299 if (!expr->holder().is_null()) { 6299 if (!holder.is_null()) {
6300 AddInstruction(new(zone()) HCheckPrototypeMaps( 6300 AddInstruction(new(zone()) HCheckPrototypeMaps(
6301 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), 6301 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), holder));
6302 expr->holder()));
6303 } 6302 }
6304 } 6303 }
6305 6304
6306 6305
6307 class FunctionSorter { 6306 class FunctionSorter {
6308 public: 6307 public:
6309 FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { } 6308 FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { }
6310 FunctionSorter(int index, int ticks, int ast_length, int src_length) 6309 FunctionSorter(int index, int ticks, int ast_length, int src_length)
6311 : index_(index), 6310 : index_(index),
6312 ticks_(ticks), 6311 ticks_(ticks),
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
6375 join = graph()->CreateBasicBlock(); 6374 join = graph()->CreateBasicBlock();
6376 } 6375 }
6377 HBasicBlock* if_true = graph()->CreateBasicBlock(); 6376 HBasicBlock* if_true = graph()->CreateBasicBlock();
6378 HBasicBlock* if_false = graph()->CreateBasicBlock(); 6377 HBasicBlock* if_false = graph()->CreateBasicBlock();
6379 HCompareMap* compare = 6378 HCompareMap* compare =
6380 new(zone()) HCompareMap(receiver, map, if_true, if_false); 6379 new(zone()) HCompareMap(receiver, map, if_true, if_false);
6381 current_block()->Finish(compare); 6380 current_block()->Finish(compare);
6382 6381
6383 set_current_block(if_true); 6382 set_current_block(if_true);
6384 expr->ComputeTarget(map, name); 6383 expr->ComputeTarget(map, name);
6385 AddCheckConstantFunction(expr, receiver, map, false); 6384 AddCheckConstantFunction(expr->holder(), receiver, map, false);
6386 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) { 6385 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) {
6387 Handle<JSFunction> caller = info()->closure(); 6386 Handle<JSFunction> caller = info()->closure();
6388 SmartArrayPointer<char> caller_name = 6387 SmartArrayPointer<char> caller_name =
6389 caller->shared()->DebugName()->ToCString(); 6388 caller->shared()->DebugName()->ToCString();
6390 PrintF("Trying to inline the polymorphic call to %s from %s\n", 6389 PrintF("Trying to inline the polymorphic call to %s from %s\n",
6391 *name->ToCString(), 6390 *name->ToCString(),
6392 *caller_name); 6391 *caller_name);
6393 } 6392 }
6394 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) { 6393 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) {
6395 // Trying to inline will signal that we should bailout from the 6394 // Trying to inline will signal that we should bailout from the
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
6882 break; 6881 break;
6883 case kMathRound: 6882 case kMathRound:
6884 case kMathFloor: 6883 case kMathFloor:
6885 case kMathAbs: 6884 case kMathAbs:
6886 case kMathSqrt: 6885 case kMathSqrt:
6887 case kMathLog: 6886 case kMathLog:
6888 case kMathSin: 6887 case kMathSin:
6889 case kMathCos: 6888 case kMathCos:
6890 case kMathTan: 6889 case kMathTan:
6891 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { 6890 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
6892 AddCheckConstantFunction(expr, receiver, receiver_map, true); 6891 AddCheckConstantFunction(expr->holder(), receiver, receiver_map, true);
6893 HValue* argument = Pop(); 6892 HValue* argument = Pop();
6894 HValue* context = environment()->LookupContext(); 6893 HValue* context = environment()->LookupContext();
6895 Drop(1); // Receiver. 6894 Drop(1); // Receiver.
6896 HUnaryMathOperation* op = 6895 HUnaryMathOperation* op =
6897 new(zone()) HUnaryMathOperation(context, argument, id); 6896 new(zone()) HUnaryMathOperation(context, argument, id);
6898 op->set_position(expr->position()); 6897 op->set_position(expr->position());
6899 ast_context()->ReturnInstruction(op, expr->id()); 6898 ast_context()->ReturnInstruction(op, expr->id());
6900 return true; 6899 return true;
6901 } 6900 }
6902 break; 6901 break;
6903 case kMathPow: 6902 case kMathPow:
6904 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 6903 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
6905 AddCheckConstantFunction(expr, receiver, receiver_map, true); 6904 AddCheckConstantFunction(expr->holder(), receiver, receiver_map, true);
6906 HValue* right = Pop(); 6905 HValue* right = Pop();
6907 HValue* left = Pop(); 6906 HValue* left = Pop();
6908 Pop(); // Pop receiver. 6907 Pop(); // Pop receiver.
6909 HValue* context = environment()->LookupContext(); 6908 HValue* context = environment()->LookupContext();
6910 HInstruction* result = NULL; 6909 HInstruction* result = NULL;
6911 // Use sqrt() if exponent is 0.5 or -0.5. 6910 // Use sqrt() if exponent is 0.5 or -0.5.
6912 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { 6911 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) {
6913 double exponent = HConstant::cast(right)->DoubleValue(); 6912 double exponent = HConstant::cast(right)->DoubleValue();
6914 if (exponent == 0.5) { 6913 if (exponent == 0.5) {
6915 result = 6914 result =
(...skipping 21 matching lines...) Expand all
6937 6936
6938 if (result == NULL) { 6937 if (result == NULL) {
6939 result = new(zone()) HPower(left, right); 6938 result = new(zone()) HPower(left, right);
6940 } 6939 }
6941 ast_context()->ReturnInstruction(result, expr->id()); 6940 ast_context()->ReturnInstruction(result, expr->id());
6942 return true; 6941 return true;
6943 } 6942 }
6944 break; 6943 break;
6945 case kMathRandom: 6944 case kMathRandom:
6946 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { 6945 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) {
6947 AddCheckConstantFunction(expr, receiver, receiver_map, true); 6946 AddCheckConstantFunction(expr->holder(), receiver, receiver_map, true);
6948 Drop(1); // Receiver. 6947 Drop(1); // Receiver.
6949 HValue* context = environment()->LookupContext(); 6948 HValue* context = environment()->LookupContext();
6950 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 6949 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
6951 AddInstruction(global_object); 6950 AddInstruction(global_object);
6952 HRandom* result = new(zone()) HRandom(global_object); 6951 HRandom* result = new(zone()) HRandom(global_object);
6953 ast_context()->ReturnInstruction(result, expr->id()); 6952 ast_context()->ReturnInstruction(result, expr->id());
6954 return true; 6953 return true;
6955 } 6954 }
6956 break; 6955 break;
6957 case kMathMax: 6956 case kMathMax:
6958 case kMathMin: 6957 case kMathMin:
6959 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 6958 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
6960 AddCheckConstantFunction(expr, receiver, receiver_map, true); 6959 AddCheckConstantFunction(expr->holder(), receiver, receiver_map, true);
6961 HValue* right = Pop(); 6960 HValue* right = Pop();
6962 HValue* left = Pop(); 6961 HValue* left = Pop();
6963 Pop(); // Pop receiver. 6962 Pop(); // Pop receiver.
6964 6963
6965 HValue* left_operand = left; 6964 HValue* left_operand = left;
6966 HValue* right_operand = right; 6965 HValue* right_operand = right;
6967 6966
6968 // If we do not have two integers, we convert to double for comparison. 6967 // If we do not have two integers, we convert to double for comparison.
6969 if (!left->representation().IsInteger32() || 6968 if (!left->representation().IsInteger32() ||
6970 !right->representation().IsInteger32()) { 6969 !right->representation().IsInteger32()) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
7066 7065
7067 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); 7066 VariableProxy* arg_two = args->at(1)->AsVariableProxy();
7068 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; 7067 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false;
7069 HValue* arg_two_value = environment()->Lookup(arg_two->var()); 7068 HValue* arg_two_value = environment()->Lookup(arg_two->var());
7070 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; 7069 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
7071 7070
7072 // Found pattern f.apply(receiver, arguments). 7071 // Found pattern f.apply(receiver, arguments).
7073 VisitForValue(prop->obj()); 7072 VisitForValue(prop->obj());
7074 if (HasStackOverflow() || current_block() == NULL) return true; 7073 if (HasStackOverflow() || current_block() == NULL) return true;
7075 HValue* function = Top(); 7074 HValue* function = Top();
7076 AddCheckConstantFunction(expr, function, function_map, true); 7075 AddCheckConstantFunction(expr->holder(), function, function_map, true);
7077 Drop(1); 7076 Drop(1);
7078 7077
7079 VisitForValue(args->at(0)); 7078 VisitForValue(args->at(0));
7080 if (HasStackOverflow() || current_block() == NULL) return true; 7079 if (HasStackOverflow() || current_block() == NULL) return true;
7081 HValue* receiver = Pop(); 7080 HValue* receiver = Pop();
7082 7081
7083 if (function_state()->outer() == NULL) { 7082 if (function_state()->outer() == NULL) {
7084 HInstruction* elements = AddInstruction( 7083 HInstruction* elements = AddInstruction(
7085 new(zone()) HArgumentsElements(false)); 7084 new(zone()) HArgumentsElements(false));
7086 HInstruction* length = 7085 HInstruction* length =
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
7185 7184
7186 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || 7185 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) ||
7187 expr->check_type() != RECEIVER_MAP_CHECK) { 7186 expr->check_type() != RECEIVER_MAP_CHECK) {
7188 // When the target has a custom call IC generator, use the IC, 7187 // When the target has a custom call IC generator, use the IC,
7189 // because it is likely to generate better code. Also use the IC 7188 // because it is likely to generate better code. Also use the IC
7190 // when a primitive receiver check is required. 7189 // when a primitive receiver check is required.
7191 HValue* context = environment()->LookupContext(); 7190 HValue* context = environment()->LookupContext();
7192 call = PreProcessCall( 7191 call = PreProcessCall(
7193 new(zone()) HCallNamed(context, name, argument_count)); 7192 new(zone()) HCallNamed(context, name, argument_count));
7194 } else { 7193 } else {
7195 AddCheckConstantFunction(expr, receiver, receiver_map, true); 7194 AddCheckConstantFunction(expr->holder(), receiver, receiver_map, true);
7196 7195
7197 if (TryInlineCall(expr)) return; 7196 if (TryInlineCall(expr)) return;
7198 call = PreProcessCall( 7197 call = PreProcessCall(
7199 new(zone()) HCallConstantFunction(expr->target(), 7198 new(zone()) HCallConstantFunction(expr->target(),
7200 argument_count)); 7199 argument_count));
7201 } 7200 }
7202 } else if (types != NULL && types->length() > 1) { 7201 } else if (types != NULL && types->length() > 1) {
7203 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); 7202 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK);
7204 HandlePolymorphicCallNamed(expr, receiver, types, name); 7203 HandlePolymorphicCallNamed(expr, receiver, types, name);
7205 return; 7204 return;
(...skipping 2313 matching lines...) Expand 10 before | Expand all | Expand 10 after
9519 } 9518 }
9520 } 9519 }
9521 9520
9522 #ifdef DEBUG 9521 #ifdef DEBUG
9523 if (graph_ != NULL) graph_->Verify(false); // No full verify. 9522 if (graph_ != NULL) graph_->Verify(false); // No full verify.
9524 if (allocator_ != NULL) allocator_->Verify(); 9523 if (allocator_ != NULL) allocator_->Verify();
9525 #endif 9524 #endif
9526 } 9525 }
9527 9526
9528 } } // namespace v8::internal 9527 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698