OLD | NEW |
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 <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 8207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8218 } | 8218 } |
8219 break; | 8219 break; |
8220 default: | 8220 default: |
8221 // Not supported for inlining yet. | 8221 // Not supported for inlining yet. |
8222 break; | 8222 break; |
8223 } | 8223 } |
8224 return false; | 8224 return false; |
8225 } | 8225 } |
8226 | 8226 |
8227 | 8227 |
| 8228 // static |
| 8229 bool HOptimizedGraphBuilder::CanInlineArrayResizeOperation( |
| 8230 Handle<Map> receiver_map) { |
| 8231 return !receiver_map.is_null() && |
| 8232 receiver_map->instance_type() == JS_ARRAY_TYPE && |
| 8233 IsFastElementsKind(receiver_map->elements_kind()) && |
| 8234 !receiver_map->is_dictionary_map() && |
| 8235 !JSArray::IsReadOnlyLengthDescriptor(receiver_map) && |
| 8236 !receiver_map->is_observed() && receiver_map->is_extensible(); |
| 8237 } |
| 8238 |
| 8239 |
8228 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( | 8240 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
8229 Call* expr, Handle<JSFunction> function, Handle<Map> receiver_map, | 8241 Call* expr, Handle<JSFunction> function, Handle<Map> receiver_map, |
8230 int args_count_no_receiver) { | 8242 int args_count_no_receiver) { |
8231 if (!function->shared()->HasBuiltinFunctionId()) return false; | 8243 if (!function->shared()->HasBuiltinFunctionId()) return false; |
8232 BuiltinFunctionId id = function->shared()->builtin_function_id(); | 8244 BuiltinFunctionId id = function->shared()->builtin_function_id(); |
8233 int argument_count = args_count_no_receiver + 1; // Plus receiver. | 8245 int argument_count = args_count_no_receiver + 1; // Plus receiver. |
8234 | 8246 |
8235 if (receiver_map.is_null()) { | 8247 if (receiver_map.is_null()) { |
8236 HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver); | 8248 HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver); |
8237 if (receiver->IsConstant() && | 8249 if (receiver->IsConstant() && |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8337 HValue* right = Pop(); | 8349 HValue* right = Pop(); |
8338 HValue* left = Pop(); | 8350 HValue* left = Pop(); |
8339 Drop(2); // Receiver and function. | 8351 Drop(2); // Receiver and function. |
8340 HInstruction* result = | 8352 HInstruction* result = |
8341 HMul::NewImul(isolate(), zone(), context(), left, right); | 8353 HMul::NewImul(isolate(), zone(), context(), left, right); |
8342 ast_context()->ReturnInstruction(result, expr->id()); | 8354 ast_context()->ReturnInstruction(result, expr->id()); |
8343 return true; | 8355 return true; |
8344 } | 8356 } |
8345 break; | 8357 break; |
8346 case kArrayPop: { | 8358 case kArrayPop: { |
8347 if (receiver_map.is_null()) return false; | 8359 if (!CanInlineArrayResizeOperation(receiver_map)) return false; |
8348 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; | |
8349 ElementsKind elements_kind = receiver_map->elements_kind(); | 8360 ElementsKind elements_kind = receiver_map->elements_kind(); |
8350 if (JSArray::IsReadOnlyLengthDescriptor(receiver_map)) return false; | |
8351 if (!IsFastElementsKind(elements_kind)) return false; | |
8352 if (receiver_map->is_observed()) return false; | |
8353 if (!receiver_map->is_extensible()) return false; | |
8354 | 8361 |
8355 Drop(args_count_no_receiver); | 8362 Drop(args_count_no_receiver); |
8356 HValue* result; | 8363 HValue* result; |
8357 HValue* reduced_length; | 8364 HValue* reduced_length; |
8358 HValue* receiver = Pop(); | 8365 HValue* receiver = Pop(); |
8359 | 8366 |
8360 HValue* checked_object = AddCheckMap(receiver, receiver_map); | 8367 HValue* checked_object = AddCheckMap(receiver, receiver_map); |
8361 HValue* length = | 8368 HValue* length = |
8362 Add<HLoadNamedField>(checked_object, nullptr, | 8369 Add<HLoadNamedField>(checked_object, nullptr, |
8363 HObjectAccess::ForArrayLength(elements_kind)); | 8370 HObjectAccess::ForArrayLength(elements_kind)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8400 length_checker.End(); | 8407 length_checker.End(); |
8401 } | 8408 } |
8402 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); | 8409 result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top(); |
8403 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 8410 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
8404 if (!ast_context()->IsEffect()) Drop(1); | 8411 if (!ast_context()->IsEffect()) Drop(1); |
8405 | 8412 |
8406 ast_context()->ReturnValue(result); | 8413 ast_context()->ReturnValue(result); |
8407 return true; | 8414 return true; |
8408 } | 8415 } |
8409 case kArrayPush: { | 8416 case kArrayPush: { |
8410 if (receiver_map.is_null()) return false; | 8417 if (!CanInlineArrayResizeOperation(receiver_map)) return false; |
8411 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; | |
8412 ElementsKind elements_kind = receiver_map->elements_kind(); | 8418 ElementsKind elements_kind = receiver_map->elements_kind(); |
8413 if (!IsFastElementsKind(elements_kind)) return false; | |
8414 if (receiver_map->is_observed()) return false; | |
8415 if (JSArray::IsReadOnlyLengthDescriptor(receiver_map)) return false; | |
8416 if (!receiver_map->is_extensible()) return false; | |
8417 | 8419 |
8418 // If there may be elements accessors in the prototype chain, the fast | 8420 // If there may be elements accessors in the prototype chain, the fast |
8419 // inlined version can't be used. | 8421 // inlined version can't be used. |
8420 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; | 8422 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; |
8421 // If there currently can be no elements accessors on the prototype chain, | 8423 // If there currently can be no elements accessors on the prototype chain, |
8422 // it doesn't mean that there won't be any later. Install a full prototype | 8424 // it doesn't mean that there won't be any later. Install a full prototype |
8423 // chain check to trap element accessors being installed on the prototype | 8425 // chain check to trap element accessors being installed on the prototype |
8424 // chain, which would cause elements to go to dictionary mode and result | 8426 // chain, which would cause elements to go to dictionary mode and result |
8425 // in a map change. | 8427 // in a map change. |
8426 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); | 8428 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); |
(...skipping 26 matching lines...) Expand all Loading... |
8453 | 8455 |
8454 if (!ast_context()->IsEffect()) Push(new_size); | 8456 if (!ast_context()->IsEffect()) Push(new_size); |
8455 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 8457 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
8456 if (!ast_context()->IsEffect()) Drop(1); | 8458 if (!ast_context()->IsEffect()) Drop(1); |
8457 } | 8459 } |
8458 | 8460 |
8459 ast_context()->ReturnValue(new_size); | 8461 ast_context()->ReturnValue(new_size); |
8460 return true; | 8462 return true; |
8461 } | 8463 } |
8462 case kArrayShift: { | 8464 case kArrayShift: { |
8463 if (receiver_map.is_null()) return false; | 8465 if (!CanInlineArrayResizeOperation(receiver_map)) return false; |
8464 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; | |
8465 ElementsKind kind = receiver_map->elements_kind(); | 8466 ElementsKind kind = receiver_map->elements_kind(); |
8466 if (JSArray::IsReadOnlyLengthDescriptor(receiver_map)) return false; | |
8467 if (!IsFastElementsKind(kind)) return false; | |
8468 if (receiver_map->is_observed()) return false; | |
8469 if (!receiver_map->is_extensible()) return false; | |
8470 | 8467 |
8471 // If there may be elements accessors in the prototype chain, the fast | 8468 // If there may be elements accessors in the prototype chain, the fast |
8472 // inlined version can't be used. | 8469 // inlined version can't be used. |
8473 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; | 8470 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; |
8474 | 8471 |
8475 // If there currently can be no elements accessors on the prototype chain, | 8472 // If there currently can be no elements accessors on the prototype chain, |
8476 // it doesn't mean that there won't be any later. Install a full prototype | 8473 // it doesn't mean that there won't be any later. Install a full prototype |
8477 // chain check to trap element accessors being installed on the prototype | 8474 // chain check to trap element accessors being installed on the prototype |
8478 // chain, which would cause elements to go to dictionary mode and result | 8475 // chain, which would cause elements to go to dictionary mode and result |
8479 // in a map change. | 8476 // in a map change. |
(...skipping 5002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13482 if (ShouldProduceTraceOutput()) { | 13479 if (ShouldProduceTraceOutput()) { |
13483 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13480 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13484 } | 13481 } |
13485 | 13482 |
13486 #ifdef DEBUG | 13483 #ifdef DEBUG |
13487 graph_->Verify(false); // No full verify. | 13484 graph_->Verify(false); // No full verify. |
13488 #endif | 13485 #endif |
13489 } | 13486 } |
13490 | 13487 |
13491 } } // namespace v8::internal | 13488 } } // namespace v8::internal |
OLD | NEW |