| OLD | NEW |
| 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 7729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7740 } | 7740 } |
| 7741 | 7741 |
| 7742 | 7742 |
| 7743 // Checks whether allocation using the given constructor can be inlined. | 7743 // Checks whether allocation using the given constructor can be inlined. |
| 7744 static bool IsAllocationInlineable(Handle<JSFunction> constructor) { | 7744 static bool IsAllocationInlineable(Handle<JSFunction> constructor) { |
| 7745 return constructor->has_initial_map() && | 7745 return constructor->has_initial_map() && |
| 7746 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && | 7746 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && |
| 7747 constructor->initial_map()->instance_size() < HAllocateObject::kMaxSize; | 7747 constructor->initial_map()->instance_size() < HAllocateObject::kMaxSize; |
| 7748 } | 7748 } |
| 7749 | 7749 |
| 7750 static bool IsArrayConstructInlinable(Handle<JSFunction> constructor) { |
| 7751 return constructor->GetIsolate()->global_context()->array_function() == |
| 7752 *constructor; |
| 7753 } |
| 7750 | 7754 |
| 7751 void HGraphBuilder::VisitCallNew(CallNew* expr) { | 7755 void HGraphBuilder::VisitCallNew(CallNew* expr) { |
| 7752 ASSERT(!HasStackOverflow()); | 7756 ASSERT(!HasStackOverflow()); |
| 7753 ASSERT(current_block() != NULL); | 7757 ASSERT(current_block() != NULL); |
| 7754 ASSERT(current_block()->HasPredecessor()); | 7758 ASSERT(current_block()->HasPredecessor()); |
| 7755 expr->RecordTypeFeedback(oracle()); | 7759 expr->RecordTypeFeedback(oracle()); |
| 7756 int argument_count = expr->arguments()->length() + 1; // Plus constructor. | 7760 int argument_count = expr->arguments()->length() + 1; // Plus constructor. |
| 7757 HValue* context = environment()->LookupContext(); | 7761 HValue* context = environment()->LookupContext(); |
| 7758 | 7762 |
| 7759 if (FLAG_inline_construct && | 7763 if (FLAG_inline_construct && |
| (...skipping 28 matching lines...) Expand all Loading... |
| 7788 // add HPushArgument for the arguments in case inlining failed. What we | 7792 // add HPushArgument for the arguments in case inlining failed. What we |
| 7789 // actually should do is emit HInvokeFunction on the constructor instead | 7793 // actually should do is emit HInvokeFunction on the constructor instead |
| 7790 // of using HCallNew as a fallback. | 7794 // of using HCallNew as a fallback. |
| 7791 receiver->DeleteAndReplaceWith(NULL); | 7795 receiver->DeleteAndReplaceWith(NULL); |
| 7792 check->DeleteAndReplaceWith(NULL); | 7796 check->DeleteAndReplaceWith(NULL); |
| 7793 environment()->SetExpressionStackAt(receiver_index, function); | 7797 environment()->SetExpressionStackAt(receiver_index, function); |
| 7794 HInstruction* call = PreProcessCall( | 7798 HInstruction* call = PreProcessCall( |
| 7795 new(zone()) HCallNew(context, function, argument_count)); | 7799 new(zone()) HCallNew(context, function, argument_count)); |
| 7796 call->set_position(expr->position()); | 7800 call->set_position(expr->position()); |
| 7797 return ast_context()->ReturnInstruction(call, expr->id()); | 7801 return ast_context()->ReturnInstruction(call, expr->id()); |
| 7802 } else if (expr->IsMonomorphic() && |
| 7803 argument_count == 1 && |
| 7804 IsArrayConstructInlinable(expr->target())) { |
| 7805 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 7806 HValue* function = Top(); |
| 7807 environment()->Drop(1); |
| 7808 Handle<JSFunction> constructor = expr->target(); |
| 7809 ElementsKind elements_kind = expr->elements_kind(); |
| 7810 AddInstruction(new(zone()) HCheckFunction(function, constructor)); |
| 7811 Factory* f = graph()->isolate()->factory(); |
| 7812 Handle<JSArray> boilerplate = f->NewEmptyJSArray(elements_kind, TENURED); |
| 7813 HValue* context = environment()->LookupContext(); |
| 7814 int total_size = JSArray::kSize + FixedArray::kHeaderSize; |
| 7815 if (IsFastDoubleElementsKind(elements_kind)) { |
| 7816 total_size += boilerplate->elements()->length() * kDoubleSize; |
| 7817 } else { |
| 7818 total_size += boilerplate->elements()->length() * kPointerSize; |
| 7819 } |
| 7820 HFastLiteral* empty_array = new(zone()) HFastLiteral(context, |
| 7821 boilerplate, |
| 7822 total_size, |
| 7823 0, |
| 7824 0); |
| 7825 return ast_context()->ReturnInstruction(empty_array, expr->id()); |
| 7798 } else { | 7826 } else { |
| 7799 // The constructor function is both an operand to the instruction and an | 7827 // The constructor function is both an operand to the instruction and an |
| 7800 // argument to the construct call. | 7828 // argument to the construct call. |
| 7801 CHECK_ALIVE(VisitArgument(expr->expression())); | 7829 CHECK_ALIVE(VisitArgument(expr->expression())); |
| 7802 HValue* constructor = HPushArgument::cast(Top())->argument(); | 7830 HValue* constructor = HPushArgument::cast(Top())->argument(); |
| 7803 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 7831 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 7804 HInstruction* call = | 7832 HInstruction* call = |
| 7805 new(zone()) HCallNew(context, constructor, argument_count); | 7833 new(zone()) HCallNew(context, constructor, argument_count); |
| 7806 Drop(argument_count); | 7834 Drop(argument_count); |
| 7807 call->set_position(expr->position()); | 7835 call->set_position(expr->position()); |
| (...skipping 2165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9973 } | 10001 } |
| 9974 } | 10002 } |
| 9975 | 10003 |
| 9976 #ifdef DEBUG | 10004 #ifdef DEBUG |
| 9977 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10005 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 9978 if (allocator_ != NULL) allocator_->Verify(); | 10006 if (allocator_ != NULL) allocator_->Verify(); |
| 9979 #endif | 10007 #endif |
| 9980 } | 10008 } |
| 9981 | 10009 |
| 9982 } } // namespace v8::internal | 10010 } } // namespace v8::internal |
| OLD | NEW |