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

Side by Side Diff: src/hydrogen.cc

Issue 588573002: Optimize Function.prototype.call (Closed) Base URL: https://github.com/v8/v8.git@master
Patch Set: Created 6 years, 3 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
« no previous file with comments | « src/hydrogen.h ('k') | src/objects.h » ('j') | no next file with comments »
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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/hydrogen.h" 5 #include "src/hydrogen.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 8066 matching lines...) Expand 10 before | Expand all | Expand 10 after
8077 if (TryInlineApiSetter(setter, receiver_map, id)) return true; 8077 if (TryInlineApiSetter(setter, receiver_map, id)) return true;
8078 return TryInline(setter, 8078 return TryInline(setter,
8079 1, 8079 1,
8080 implicit_return_value, 8080 implicit_return_value,
8081 id, assignment_id, 8081 id, assignment_id,
8082 SETTER_CALL_RETURN, 8082 SETTER_CALL_RETURN,
8083 source_position()); 8083 source_position());
8084 } 8084 }
8085 8085
8086 8086
8087 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function, 8087 bool HOptimizedGraphBuilder::TryInlineIndirectCall(Handle<JSFunction> function,
8088 Call* expr, 8088 Call* expr,
8089 int arguments_count) { 8089 int arguments_count) {
8090 return TryInline(function, 8090 return TryInline(function,
8091 arguments_count, 8091 arguments_count,
8092 NULL, 8092 NULL,
8093 expr->id(), 8093 expr->id(),
8094 expr->ReturnId(), 8094 expr->ReturnId(),
8095 NORMAL_RETURN, 8095 NORMAL_RETURN,
8096 ScriptPositionToSourcePosition(expr->position())); 8096 ScriptPositionToSourcePosition(expr->position()));
8097 } 8097 }
8098 8098
8099 8099
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
8131 break; 8131 break;
8132 default: 8132 default:
8133 // Not supported for inlining yet. 8133 // Not supported for inlining yet.
8134 break; 8134 break;
8135 } 8135 }
8136 return false; 8136 return false;
8137 } 8137 }
8138 8138
8139 8139
8140 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( 8140 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
8141 Call* expr, 8141 Call* expr, Handle<JSFunction> function, Handle<Map> receiver_map,
8142 HValue* receiver, 8142 int args_count_no_receiver) {
8143 Handle<Map> receiver_map) { 8143 if (!function->shared()->HasBuiltinFunctionId()) return false;
8144 BuiltinFunctionId id = function->shared()->builtin_function_id();
8145 int argument_count = args_count_no_receiver + 1; // Plus receiver.
8146
8147 if (receiver_map.is_null()) {
8148 HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver);
8149 if (receiver->IsConstant() &&
8150 HConstant::cast(receiver)->handle(isolate())->IsHeapObject()) {
8151 receiver_map =
8152 handle(Handle<HeapObject>::cast(
8153 HConstant::cast(receiver)->handle(isolate()))->map());
Toon Verwaest 2015/04/24 18:51:07 This caused a major issue since no map-check is ad
8154 }
8155 }
8144 // Try to inline calls like Math.* as operations in the calling function. 8156 // Try to inline calls like Math.* as operations in the calling function.
8145 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
8146 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
8147 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
8148 switch (id) { 8157 switch (id) {
8149 case kStringCharCodeAt: 8158 case kStringCharCodeAt:
8150 case kStringCharAt: 8159 case kStringCharAt:
8151 if (argument_count == 2) { 8160 if (argument_count == 2) {
8152 HValue* index = Pop(); 8161 HValue* index = Pop();
8153 HValue* string = Pop(); 8162 HValue* string = Pop();
8154 Drop(1); // Function. 8163 Drop(1); // Function.
8155 HInstruction* char_code = 8164 HInstruction* char_code =
8156 BuildStringCharCodeAt(string, index); 8165 BuildStringCharCodeAt(string, index);
8157 if (id == kStringCharCodeAt) { 8166 if (id == kStringCharCodeAt) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
8246 } 8255 }
8247 break; 8256 break;
8248 case kArrayPop: { 8257 case kArrayPop: {
8249 if (receiver_map.is_null()) return false; 8258 if (receiver_map.is_null()) return false;
8250 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 8259 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
8251 ElementsKind elements_kind = receiver_map->elements_kind(); 8260 ElementsKind elements_kind = receiver_map->elements_kind();
8252 if (!IsFastElementsKind(elements_kind)) return false; 8261 if (!IsFastElementsKind(elements_kind)) return false;
8253 if (receiver_map->is_observed()) return false; 8262 if (receiver_map->is_observed()) return false;
8254 if (!receiver_map->is_extensible()) return false; 8263 if (!receiver_map->is_extensible()) return false;
8255 8264
8256 Drop(expr->arguments()->length()); 8265 Drop(args_count_no_receiver);
8257 HValue* result; 8266 HValue* result;
8258 HValue* reduced_length; 8267 HValue* reduced_length;
8259 HValue* receiver = Pop(); 8268 HValue* receiver = Pop();
8260 8269
8261 HValue* checked_object = AddCheckMap(receiver, receiver_map); 8270 HValue* checked_object = AddCheckMap(receiver, receiver_map);
8262 HValue* length = Add<HLoadNamedField>( 8271 HValue* length = Add<HLoadNamedField>(
8263 checked_object, static_cast<HValue*>(NULL), 8272 checked_object, static_cast<HValue*>(NULL),
8264 HObjectAccess::ForArrayLength(elements_kind)); 8273 HObjectAccess::ForArrayLength(elements_kind));
8265 8274
8266 Drop(1); // Function. 8275 Drop(1); // Function.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
8322 // inlined version can't be used. 8331 // inlined version can't be used.
8323 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 8332 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false;
8324 // If there currently can be no elements accessors on the prototype chain, 8333 // If there currently can be no elements accessors on the prototype chain,
8325 // it doesn't mean that there won't be any later. Install a full prototype 8334 // it doesn't mean that there won't be any later. Install a full prototype
8326 // chain check to trap element accessors being installed on the prototype 8335 // chain check to trap element accessors being installed on the prototype
8327 // chain, which would cause elements to go to dictionary mode and result 8336 // chain, which would cause elements to go to dictionary mode and result
8328 // in a map change. 8337 // in a map change.
8329 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 8338 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
8330 BuildCheckPrototypeMaps(prototype, Handle<JSObject>()); 8339 BuildCheckPrototypeMaps(prototype, Handle<JSObject>());
8331 8340
8332 const int argc = expr->arguments()->length(); 8341 const int argc = args_count_no_receiver;
8333 if (argc != 1) return false; 8342 if (argc != 1) return false;
8334 8343
8335 HValue* value_to_push = Pop(); 8344 HValue* value_to_push = Pop();
8336 HValue* array = Pop(); 8345 HValue* array = Pop();
8337 Drop(1); // Drop function. 8346 Drop(1); // Drop function.
8338 8347
8339 HInstruction* new_size = NULL; 8348 HInstruction* new_size = NULL;
8340 HValue* length = NULL; 8349 HValue* length = NULL;
8341 8350
8342 { 8351 {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
8379 // chain check to trap element accessors being installed on the prototype 8388 // chain check to trap element accessors being installed on the prototype
8380 // chain, which would cause elements to go to dictionary mode and result 8389 // chain, which would cause elements to go to dictionary mode and result
8381 // in a map change. 8390 // in a map change.
8382 BuildCheckPrototypeMaps( 8391 BuildCheckPrototypeMaps(
8383 handle(JSObject::cast(receiver_map->prototype()), isolate()), 8392 handle(JSObject::cast(receiver_map->prototype()), isolate()),
8384 Handle<JSObject>::null()); 8393 Handle<JSObject>::null());
8385 8394
8386 // Threshold for fast inlined Array.shift(). 8395 // Threshold for fast inlined Array.shift().
8387 HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16)); 8396 HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16));
8388 8397
8389 Drop(expr->arguments()->length()); 8398 Drop(args_count_no_receiver);
8390 HValue* receiver = Pop(); 8399 HValue* receiver = Pop();
8391 HValue* function = Pop(); 8400 HValue* function = Pop();
8392 HValue* result; 8401 HValue* result;
8393 8402
8394 { 8403 {
8395 NoObservableSideEffectsScope scope(this); 8404 NoObservableSideEffectsScope scope(this);
8396 8405
8397 HValue* length = Add<HLoadNamedField>( 8406 HValue* length = Add<HLoadNamedField>(
8398 receiver, static_cast<HValue*>(NULL), 8407 receiver, static_cast<HValue*>(NULL),
8399 HObjectAccess::ForArrayLength(kind)); 8408 HObjectAccess::ForArrayLength(kind));
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
8685 HInstruction* call = New<HCallWithDescriptor>( 8694 HInstruction* call = New<HCallWithDescriptor>(
8686 code_value, argc + 1, descriptor, 8695 code_value, argc + 1, descriptor,
8687 Vector<HValue*>(op_vals, descriptor.GetEnvironmentLength())); 8696 Vector<HValue*>(op_vals, descriptor.GetEnvironmentLength()));
8688 8697
8689 if (drop_extra) Drop(1); // Drop function. 8698 if (drop_extra) Drop(1); // Drop function.
8690 ast_context()->ReturnInstruction(call, ast_id); 8699 ast_context()->ReturnInstruction(call, ast_id);
8691 return true; 8700 return true;
8692 } 8701 }
8693 8702
8694 8703
8695 bool HOptimizedGraphBuilder::TryCallApply(Call* expr) { 8704 void HOptimizedGraphBuilder::HandleIndirectCall(Call* expr, HValue* function,
8705 int arguments_count) {
8706 Handle<JSFunction> known_function;
8707 int args_count_no_receiver = arguments_count - 1;
8708 if (function->IsConstant() &&
8709 HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
8710 HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver);
8711 Handle<Map> receiver_map;
8712 if (receiver->IsConstant() &&
8713 HConstant::cast(receiver)->handle(isolate())->IsHeapObject()) {
8714 receiver_map =
8715 handle(Handle<HeapObject>::cast(
8716 HConstant::cast(receiver)->handle(isolate()))->map());
8717 }
8718
8719 known_function =
8720 Handle<JSFunction>::cast(HConstant::cast(function)->handle(isolate()));
8721 if (TryInlineBuiltinMethodCall(expr, known_function, receiver_map,
8722 args_count_no_receiver)) {
8723 if (FLAG_trace_inlining) {
8724 PrintF("Inlining builtin ");
8725 known_function->ShortPrint();
8726 PrintF("\n");
8727 }
8728 return;
8729 }
8730
8731 if (TryInlineIndirectCall(known_function, expr, args_count_no_receiver)) {
8732 return;
8733 }
8734 }
8735
8736 PushArgumentsFromEnvironment(arguments_count);
8737 HInvokeFunction* call =
8738 New<HInvokeFunction>(function, known_function, arguments_count);
8739 Drop(1); // Function
8740 ast_context()->ReturnInstruction(call, expr->id());
8741 }
8742
8743
8744 bool HOptimizedGraphBuilder::TryIndirectCall(Call* expr) {
8696 DCHECK(expr->expression()->IsProperty()); 8745 DCHECK(expr->expression()->IsProperty());
8697 8746
8698 if (!expr->IsMonomorphic()) { 8747 if (!expr->IsMonomorphic()) {
8699 return false; 8748 return false;
8700 } 8749 }
8701 Handle<Map> function_map = expr->GetReceiverTypes()->first(); 8750 Handle<Map> function_map = expr->GetReceiverTypes()->first();
8702 if (function_map->instance_type() != JS_FUNCTION_TYPE || 8751 if (function_map->instance_type() != JS_FUNCTION_TYPE ||
8703 !expr->target()->shared()->HasBuiltinFunctionId() || 8752 !expr->target()->shared()->HasBuiltinFunctionId()) {
8704 expr->target()->shared()->builtin_function_id() != kFunctionApply) {
8705 return false; 8753 return false;
8706 } 8754 }
8707 8755
8708 if (current_info()->scope()->arguments() == NULL) return false; 8756 switch (expr->target()->shared()->builtin_function_id()) {
8757 case kFunctionCall: {
8758 if (expr->arguments()->length() == 0) return false;
8759 BuildFunctionCall(expr);
8760 return true;
8761 }
8762 case kFunctionApply: {
8763 // For .apply, only the pattern f.apply(receiver, arguments)
8764 // is supported.
8765 if (current_info()->scope()->arguments() == NULL) return false;
8709 8766
8767 ZoneList<Expression*>* args = expr->arguments();
8768 if (args->length() != 2) return false;
8769
8770 VariableProxy* arg_two = args->at(1)->AsVariableProxy();
8771 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false;
8772 HValue* arg_two_value = LookupAndMakeLive(arg_two->var());
8773 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
8774 BuildFunctionApply(expr);
8775 return true;
8776 }
8777 default: { return false; }
8778 }
8779 UNREACHABLE();
8780 }
8781
8782
8783 void HOptimizedGraphBuilder::BuildFunctionApply(Call* expr) {
8710 ZoneList<Expression*>* args = expr->arguments(); 8784 ZoneList<Expression*>* args = expr->arguments();
8711 if (args->length() != 2) return false; 8785 CHECK_ALIVE(VisitForValue(args->at(0)));
8712
8713 VariableProxy* arg_two = args->at(1)->AsVariableProxy();
8714 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false;
8715 HValue* arg_two_value = LookupAndMakeLive(arg_two->var());
8716 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
8717
8718 // Found pattern f.apply(receiver, arguments).
8719 CHECK_ALIVE_OR_RETURN(VisitForValue(args->at(0)), true);
8720 HValue* receiver = Pop(); // receiver 8786 HValue* receiver = Pop(); // receiver
8721 HValue* function = Pop(); // f 8787 HValue* function = Pop(); // f
8722 Drop(1); // apply 8788 Drop(1); // apply
8723 8789
8790 Handle<Map> function_map = expr->GetReceiverTypes()->first();
8724 HValue* checked_function = AddCheckMap(function, function_map); 8791 HValue* checked_function = AddCheckMap(function, function_map);
8725 8792
8726 if (function_state()->outer() == NULL) { 8793 if (function_state()->outer() == NULL) {
8727 HInstruction* elements = Add<HArgumentsElements>(false); 8794 HInstruction* elements = Add<HArgumentsElements>(false);
8728 HInstruction* length = Add<HArgumentsLength>(elements); 8795 HInstruction* length = Add<HArgumentsLength>(elements);
8729 HValue* wrapped_receiver = BuildWrapReceiver(receiver, checked_function); 8796 HValue* wrapped_receiver = BuildWrapReceiver(receiver, checked_function);
8730 HInstruction* result = New<HApplyArguments>(function, 8797 HInstruction* result = New<HApplyArguments>(function,
8731 wrapped_receiver, 8798 wrapped_receiver,
8732 length, 8799 length,
8733 elements); 8800 elements);
8734 ast_context()->ReturnInstruction(result, expr->id()); 8801 ast_context()->ReturnInstruction(result, expr->id());
8735 return true;
8736 } else { 8802 } else {
8737 // We are inside inlined function and we know exactly what is inside 8803 // We are inside inlined function and we know exactly what is inside
8738 // arguments object. But we need to be able to materialize at deopt. 8804 // arguments object. But we need to be able to materialize at deopt.
8739 DCHECK_EQ(environment()->arguments_environment()->parameter_count(), 8805 DCHECK_EQ(environment()->arguments_environment()->parameter_count(),
8740 function_state()->entry()->arguments_object()->arguments_count()); 8806 function_state()->entry()->arguments_object()->arguments_count());
8741 HArgumentsObject* args = function_state()->entry()->arguments_object(); 8807 HArgumentsObject* args = function_state()->entry()->arguments_object();
8742 const ZoneList<HValue*>* arguments_values = args->arguments_values(); 8808 const ZoneList<HValue*>* arguments_values = args->arguments_values();
8743 int arguments_count = arguments_values->length(); 8809 int arguments_count = arguments_values->length();
8744 Push(function); 8810 Push(function);
8745 Push(BuildWrapReceiver(receiver, checked_function)); 8811 Push(BuildWrapReceiver(receiver, checked_function));
8746 for (int i = 1; i < arguments_count; i++) { 8812 for (int i = 1; i < arguments_count; i++) {
8747 Push(arguments_values->at(i)); 8813 Push(arguments_values->at(i));
8748 } 8814 }
8749 8815 HandleIndirectCall(expr, function, arguments_count);
8750 Handle<JSFunction> known_function;
8751 if (function->IsConstant() &&
8752 HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
8753 known_function = Handle<JSFunction>::cast(
8754 HConstant::cast(function)->handle(isolate()));
8755 int args_count = arguments_count - 1; // Excluding receiver.
8756 if (TryInlineApply(known_function, expr, args_count)) return true;
8757 }
8758
8759 PushArgumentsFromEnvironment(arguments_count);
8760 HInvokeFunction* call = New<HInvokeFunction>(
8761 function, known_function, arguments_count);
8762 Drop(1); // Function.
8763 ast_context()->ReturnInstruction(call, expr->id());
8764 return true;
8765 } 8816 }
8766 } 8817 }
8767 8818
8768 8819
8820 // f.call(...)
8821 void HOptimizedGraphBuilder::BuildFunctionCall(Call* expr) {
8822 HValue* function = Top(); // f
8823 Handle<Map> function_map = expr->GetReceiverTypes()->first();
8824 HValue* checked_function = AddCheckMap(function, function_map);
8825
8826 // f and call are on the stack in the unoptimized code
8827 // during evaluation of the arguments.
8828 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8829
8830 int args_length = expr->arguments()->length();
8831 int receiver_index = args_length - 1;
8832 // Patch the receiver.
8833 HValue* receiver = BuildWrapReceiver(
8834 environment()->ExpressionStackAt(receiver_index), checked_function);
8835 environment()->SetExpressionStackAt(receiver_index, receiver);
8836
8837 // Call must not be on the stack from now on.
8838 int call_index = args_length + 1;
8839 environment()->RemoveExpressionStackAt(call_index);
8840
8841 HandleIndirectCall(expr, function, args_length);
8842 }
8843
8844
8769 HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function, 8845 HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function,
8770 Handle<JSFunction> target) { 8846 Handle<JSFunction> target) {
8771 SharedFunctionInfo* shared = target->shared(); 8847 SharedFunctionInfo* shared = target->shared();
8772 if (shared->strict_mode() == SLOPPY && !shared->native()) { 8848 if (shared->strict_mode() == SLOPPY && !shared->native()) {
8773 // Cannot embed a direct reference to the global proxy 8849 // Cannot embed a direct reference to the global proxy
8774 // as is it dropped on deserialization. 8850 // as is it dropped on deserialization.
8775 CHECK(!isolate()->serializer_enabled()); 8851 CHECK(!isolate()->serializer_enabled());
8776 Handle<JSObject> global_proxy(target->context()->global_proxy()); 8852 Handle<JSObject> global_proxy(target->context()->global_proxy());
8777 return Add<HConstant>(global_proxy); 8853 return Add<HConstant>(global_proxy);
8778 } 8854 }
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
9021 environment()->SetExpressionStackAt(0, function); 9097 environment()->SetExpressionStackAt(0, function);
9022 9098
9023 Push(receiver); 9099 Push(receiver);
9024 9100
9025 if (function->IsConstant() && 9101 if (function->IsConstant() &&
9026 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 9102 HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
9027 Handle<JSFunction> known_function = Handle<JSFunction>::cast( 9103 Handle<JSFunction> known_function = Handle<JSFunction>::cast(
9028 HConstant::cast(function)->handle(isolate())); 9104 HConstant::cast(function)->handle(isolate()));
9029 expr->set_target(known_function); 9105 expr->set_target(known_function);
9030 9106
9031 if (TryCallApply(expr)) return; 9107 if (TryIndirectCall(expr)) return;
9032 CHECK_ALIVE(VisitExpressions(expr->arguments())); 9108 CHECK_ALIVE(VisitExpressions(expr->arguments()));
9033 9109
9034 Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>(); 9110 Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>();
9035 if (TryInlineBuiltinMethodCall(expr, receiver, map)) { 9111 if (TryInlineBuiltinMethodCall(expr, known_function, map,
9112 expr->arguments()->length())) {
9036 if (FLAG_trace_inlining) { 9113 if (FLAG_trace_inlining) {
9037 PrintF("Inlining builtin "); 9114 PrintF("Inlining builtin ");
9038 known_function->ShortPrint(); 9115 known_function->ShortPrint();
9039 PrintF("\n"); 9116 PrintF("\n");
9040 } 9117 }
9041 return; 9118 return;
9042 } 9119 }
9043 if (TryInlineApiMethodCall(expr, receiver, types)) return; 9120 if (TryInlineApiMethodCall(expr, receiver, types)) return;
9044 9121
9045 // Wrap the receiver if necessary. 9122 // Wrap the receiver if necessary.
(...skipping 3017 matching lines...) Expand 10 before | Expand all | Expand 10 after
12063 // the new value will not be included in this environment's history. 12140 // the new value will not be included in this environment's history.
12064 if (push_count_ < count) { 12141 if (push_count_ < count) {
12065 // This is the same effect as popping then re-pushing 'count' elements. 12142 // This is the same effect as popping then re-pushing 'count' elements.
12066 pop_count_ += (count - push_count_); 12143 pop_count_ += (count - push_count_);
12067 push_count_ = count; 12144 push_count_ = count;
12068 } 12145 }
12069 values_[index] = value; 12146 values_[index] = value;
12070 } 12147 }
12071 12148
12072 12149
12150 HValue* HEnvironment::RemoveExpressionStackAt(int index_from_top) {
12151 int count = index_from_top + 1;
12152 int index = values_.length() - count;
12153 DCHECK(HasExpressionAt(index));
12154 // Simulate popping 'count' elements and then
12155 // pushing 'count - 1' elements back.
12156 pop_count_ += Max(count - push_count_, 0);
12157 push_count_ = Max(push_count_ - count, 0) + (count - 1);
12158 return values_.Remove(index);
12159 }
12160
12161
12073 void HEnvironment::Drop(int count) { 12162 void HEnvironment::Drop(int count) {
12074 for (int i = 0; i < count; ++i) { 12163 for (int i = 0; i < count; ++i) {
12075 Pop(); 12164 Pop();
12076 } 12165 }
12077 } 12166 }
12078 12167
12079 12168
12080 HEnvironment* HEnvironment::Copy() const { 12169 HEnvironment* HEnvironment::Copy() const {
12081 return new(zone()) HEnvironment(this, zone()); 12170 return new(zone()) HEnvironment(this, zone());
12082 } 12171 }
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
12519 if (ShouldProduceTraceOutput()) { 12608 if (ShouldProduceTraceOutput()) {
12520 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12609 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12521 } 12610 }
12522 12611
12523 #ifdef DEBUG 12612 #ifdef DEBUG
12524 graph_->Verify(false); // No full verify. 12613 graph_->Verify(false); // No full verify.
12525 #endif 12614 #endif
12526 } 12615 }
12527 12616
12528 } } // namespace v8::internal 12617 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698