| 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 |