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 |