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

Side by Side Diff: src/hydrogen.cc

Issue 107933005: Templatise type representation (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years 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/code-stubs-hydrogen.cc ('k') | src/ic.h » ('j') | src/ic.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 8674 matching lines...) Expand 10 before | Expand all | Expand 10 after
8685 } 8685 }
8686 return number; 8686 return number;
8687 } 8687 }
8688 8688
8689 8689
8690 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) { 8690 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) {
8691 if (value->IsConstant()) { 8691 if (value->IsConstant()) {
8692 HConstant* constant = HConstant::cast(value); 8692 HConstant* constant = HConstant::cast(value);
8693 Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone()); 8693 Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone());
8694 if (number.has_value) { 8694 if (number.has_value) {
8695 *expected = handle(Type::Number(), isolate()); 8695 *expected = Type::Number(isolate());
8696 return AddInstruction(number.value); 8696 return AddInstruction(number.value);
8697 } 8697 }
8698 } 8698 }
8699 8699
8700 // We put temporary values on the stack, which don't correspond to anything 8700 // We put temporary values on the stack, which don't correspond to anything
8701 // in baseline code. Since nothing is observable we avoid recording those 8701 // in baseline code. Since nothing is observable we avoid recording those
8702 // pushes with a NoObservableSideEffectsScope. 8702 // pushes with a NoObservableSideEffectsScope.
8703 NoObservableSideEffectsScope no_effects(this); 8703 NoObservableSideEffectsScope no_effects(this);
8704 8704
8705 Handle<Type> expected_type = *expected; 8705 Handle<Type> expected_type = *expected;
8706 8706
8707 // Separate the number type from the rest. 8707 // Separate the number type from the rest.
8708 Handle<Type> expected_obj = handle(Type::Intersect( 8708 Handle<Type> expected_obj = Type::Intersect(
8709 expected_type, handle(Type::NonNumber(), isolate())), isolate()); 8709 expected_type, Type::NonNumber(isolate()), isolate());
8710 Handle<Type> expected_number = handle(Type::Intersect( 8710 Handle<Type> expected_number = Type::Intersect(
8711 expected_type, handle(Type::Number(), isolate())), isolate()); 8711 expected_type, Type::Number(isolate()), isolate());
8712 8712
8713 // We expect to get a number. 8713 // We expect to get a number.
8714 // (We need to check first, since Type::None->Is(Type::Any()) == true. 8714 // (We need to check first, since Type::None->Is(Type::Any()) == true.
8715 if (expected_obj->Is(Type::None())) { 8715 if (expected_obj->Is(Type::None())) {
8716 ASSERT(!expected_number->Is(Type::None())); 8716 ASSERT(!expected_number->Is(Type::None()));
8717 return value; 8717 return value;
8718 } 8718 }
8719 8719
8720 if (expected_obj->Is(Type::Undefined())) { 8720 if (expected_obj->Is(Type::Undefined())) {
8721 // This is already done by HChange. 8721 // This is already done by HChange.
8722 *expected = handle(Type::Union( 8722 *expected = Type::Union(
8723 expected_number, handle(Type::Double(), isolate())), isolate()); 8723 expected_number, Type::Double(isolate()), isolate());
8724 return value; 8724 return value;
8725 } 8725 }
8726 8726
8727 return value; 8727 return value;
8728 } 8728 }
8729 8729
8730 8730
8731 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( 8731 HValue* HOptimizedGraphBuilder::BuildBinaryOperation(
8732 BinaryOperation* expr, 8732 BinaryOperation* expr,
8733 HValue* left, 8733 HValue* left,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
8766 8766
8767 bool maybe_string_add = op == Token::ADD && 8767 bool maybe_string_add = op == Token::ADD &&
8768 (left_type->Maybe(Type::String()) || 8768 (left_type->Maybe(Type::String()) ||
8769 right_type->Maybe(Type::String())); 8769 right_type->Maybe(Type::String()));
8770 8770
8771 if (left_type->Is(Type::None())) { 8771 if (left_type->Is(Type::None())) {
8772 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", 8772 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation",
8773 Deoptimizer::SOFT); 8773 Deoptimizer::SOFT);
8774 // TODO(rossberg): we should be able to get rid of non-continuous 8774 // TODO(rossberg): we should be able to get rid of non-continuous
8775 // defaults. 8775 // defaults.
8776 left_type = handle(Type::Any(), isolate()); 8776 left_type = Type::Any(isolate());
8777 } else { 8777 } else {
8778 if (!maybe_string_add) left = TruncateToNumber(left, &left_type); 8778 if (!maybe_string_add) left = TruncateToNumber(left, &left_type);
8779 left_rep = Representation::FromType(left_type); 8779 left_rep = Representation::FromType(left_type);
8780 } 8780 }
8781 8781
8782 if (right_type->Is(Type::None())) { 8782 if (right_type->Is(Type::None())) {
8783 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation", 8783 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation",
8784 Deoptimizer::SOFT); 8784 Deoptimizer::SOFT);
8785 right_type = handle(Type::Any(), isolate()); 8785 right_type = Type::Any(isolate());
8786 } else { 8786 } else {
8787 if (!maybe_string_add) right = TruncateToNumber(right, &right_type); 8787 if (!maybe_string_add) right = TruncateToNumber(right, &right_type);
8788 right_rep = Representation::FromType(right_type); 8788 right_rep = Representation::FromType(right_type);
8789 } 8789 }
8790 8790
8791 // Special case for string addition here. 8791 // Special case for string addition here.
8792 if (op == Token::ADD && 8792 if (op == Token::ADD &&
8793 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { 8793 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) {
8794 // Validate type feedback for left argument. 8794 // Validate type feedback for left argument.
8795 if (left_type->Is(Type::String())) { 8795 if (left_type->Is(Type::String())) {
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
9217 HInstruction* result = New<HInvokeFunction>(function, 2); 9217 HInstruction* result = New<HInvokeFunction>(function, 2);
9218 return ast_context()->ReturnInstruction(result, expr->id()); 9218 return ast_context()->ReturnInstruction(result, expr->id());
9219 } 9219 }
9220 9220
9221 // Cases handled below depend on collected type feedback. They should 9221 // Cases handled below depend on collected type feedback. They should
9222 // soft deoptimize when there is no type feedback. 9222 // soft deoptimize when there is no type feedback.
9223 if (combined_type->Is(Type::None())) { 9223 if (combined_type->Is(Type::None())) {
9224 Add<HDeoptimize>("Insufficient type feedback for combined type " 9224 Add<HDeoptimize>("Insufficient type feedback for combined type "
9225 "of binary operation", 9225 "of binary operation",
9226 Deoptimizer::SOFT); 9226 Deoptimizer::SOFT);
9227 combined_type = left_type = right_type = handle(Type::Any(), isolate()); 9227 combined_type = left_type = right_type = Type::Any(isolate());
9228 } 9228 }
9229 9229
9230 if (combined_type->Is(Type::Receiver())) { 9230 if (combined_type->Is(Type::Receiver())) {
9231 switch (op) { 9231 switch (op) {
9232 case Token::EQ: 9232 case Token::EQ:
9233 case Token::EQ_STRICT: { 9233 case Token::EQ_STRICT: {
9234 // Can we get away with map check and not instance type check? 9234 // Can we get away with map check and not instance type check?
9235 if (combined_type->IsClass()) { 9235 if (combined_type->IsClass()) {
9236 Handle<Map> map = combined_type->AsClass(); 9236 Handle<Map> map = combined_type->AsClass();
9237 AddCheckMap(left, map); 9237 AddCheckMap(left, map);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
9307 if (expr->op() == Token::EQ_STRICT) { 9307 if (expr->op() == Token::EQ_STRICT) {
9308 HConstant* nil_constant = nil == kNullValue 9308 HConstant* nil_constant = nil == kNullValue
9309 ? graph()->GetConstantNull() 9309 ? graph()->GetConstantNull()
9310 : graph()->GetConstantUndefined(); 9310 : graph()->GetConstantUndefined();
9311 HCompareObjectEqAndBranch* instr = 9311 HCompareObjectEqAndBranch* instr =
9312 New<HCompareObjectEqAndBranch>(value, nil_constant); 9312 New<HCompareObjectEqAndBranch>(value, nil_constant);
9313 return ast_context()->ReturnControl(instr, expr->id()); 9313 return ast_context()->ReturnControl(instr, expr->id());
9314 } else { 9314 } else {
9315 ASSERT_EQ(Token::EQ, expr->op()); 9315 ASSERT_EQ(Token::EQ, expr->op());
9316 Handle<Type> type = expr->combined_type()->Is(Type::None()) 9316 Handle<Type> type = expr->combined_type()->Is(Type::None())
9317 ? handle(Type::Any(), isolate_) 9317 ? Type::Any(isolate_) : expr->combined_type();
9318 : expr->combined_type();
9319 HIfContinuation continuation; 9318 HIfContinuation continuation;
9320 BuildCompareNil(value, type, &continuation); 9319 BuildCompareNil(value, type, &continuation);
9321 return ast_context()->ReturnContinuation(&continuation, expr->id()); 9320 return ast_context()->ReturnContinuation(&continuation, expr->id());
9322 } 9321 }
9323 } 9322 }
9324 9323
9325 9324
9326 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { 9325 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() {
9327 // If we share optimized code between different closures, the 9326 // If we share optimized code between different closures, the
9328 // this-function is not a constant, except inside an inlined body. 9327 // this-function is not a constant, except inside an inlined body.
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after
10078 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 10077 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
10079 return Bailout(kInlinedRuntimeFunctionGetFromCache); 10078 return Bailout(kInlinedRuntimeFunctionGetFromCache);
10080 } 10079 }
10081 10080
10082 10081
10083 // Fast support for number to string. 10082 // Fast support for number to string.
10084 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { 10083 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
10085 ASSERT_EQ(1, call->arguments()->length()); 10084 ASSERT_EQ(1, call->arguments()->length());
10086 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10085 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10087 HValue* number = Pop(); 10086 HValue* number = Pop();
10088 HValue* result = BuildNumberToString( 10087 HValue* result = BuildNumberToString(number, Type::Number(isolate()));
10089 number, handle(Type::Number(), isolate()));
10090 return ast_context()->ReturnValue(result); 10088 return ast_context()->ReturnValue(result);
10091 } 10089 }
10092 10090
10093 10091
10094 // Fast call for custom callbacks. 10092 // Fast call for custom callbacks.
10095 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { 10093 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) {
10096 // 1 ~ The function to call is not itself an argument to the call. 10094 // 1 ~ The function to call is not itself an argument to the call.
10097 int arg_count = call->arguments()->length() - 1; 10095 int arg_count = call->arguments()->length() - 1;
10098 ASSERT(arg_count >= 1); // There's always at least a receiver. 10096 ASSERT(arg_count >= 1); // There's always at least a receiver.
10099 10097
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after
10811 if (ShouldProduceTraceOutput()) { 10809 if (ShouldProduceTraceOutput()) {
10812 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 10810 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
10813 } 10811 }
10814 10812
10815 #ifdef DEBUG 10813 #ifdef DEBUG
10816 graph_->Verify(false); // No full verify. 10814 graph_->Verify(false); // No full verify.
10817 #endif 10815 #endif
10818 } 10816 }
10819 10817
10820 } } // namespace v8::internal 10818 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs-hydrogen.cc ('k') | src/ic.h » ('j') | src/ic.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698