Chromium Code Reviews| 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 "hydrogen.h" | 5 #include "hydrogen.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "v8.h" | 9 #include "v8.h" |
| 10 #include "allocation-site-scopes.h" | 10 #include "allocation-site-scopes.h" |
| (...skipping 2450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2461 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 2461 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
| 2462 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 2462 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
| 2463 ? Add<HConstant>(factory->the_hole_value()) | 2463 ? Add<HConstant>(factory->the_hole_value()) |
| 2464 : Add<HConstant>(nan_double); | 2464 : Add<HConstant>(nan_double); |
| 2465 | 2465 |
| 2466 if (to == NULL) { | 2466 if (to == NULL) { |
| 2467 to = AddLoadFixedArrayLength(elements); | 2467 to = AddLoadFixedArrayLength(elements); |
| 2468 } | 2468 } |
| 2469 | 2469 |
| 2470 // Special loop unfolding case | 2470 // Special loop unfolding case |
| 2471 static const int kLoopUnfoldLimit = 8; | |
| 2472 STATIC_ASSERT(JSArray::kPreallocatedArrayElements <= kLoopUnfoldLimit); | 2471 STATIC_ASSERT(JSArray::kPreallocatedArrayElements <= kLoopUnfoldLimit); |
| 2473 int initial_capacity = -1; | 2472 int initial_capacity = -1; |
| 2474 if (from->IsInteger32Constant() && to->IsInteger32Constant()) { | 2473 if (from->IsInteger32Constant() && to->IsInteger32Constant()) { |
| 2475 int constant_from = from->GetInteger32Constant(); | 2474 int constant_from = from->GetInteger32Constant(); |
| 2476 int constant_to = to->GetInteger32Constant(); | 2475 int constant_to = to->GetInteger32Constant(); |
| 2477 | 2476 |
| 2478 if (constant_from == 0 && constant_to <= kLoopUnfoldLimit) { | 2477 if (constant_from == 0 && constant_to <= kLoopUnfoldLimit) { |
| 2479 initial_capacity = constant_to; | 2478 initial_capacity = constant_to; |
| 2480 } | 2479 } |
| 2481 } | 2480 } |
| (...skipping 5743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8225 // as is it dropped on deserialization. | 8224 // as is it dropped on deserialization. |
| 8226 CHECK(!Serializer::enabled(isolate())); | 8225 CHECK(!Serializer::enabled(isolate())); |
| 8227 Handle<JSObject> global_receiver( | 8226 Handle<JSObject> global_receiver( |
| 8228 target->context()->global_object()->global_receiver()); | 8227 target->context()->global_object()->global_receiver()); |
| 8229 return Add<HConstant>(global_receiver); | 8228 return Add<HConstant>(global_receiver); |
| 8230 } | 8229 } |
| 8231 return graph()->GetConstantUndefined(); | 8230 return graph()->GetConstantUndefined(); |
| 8232 } | 8231 } |
| 8233 | 8232 |
| 8234 | 8233 |
| 8234 void HOptimizedGraphBuilder::BuildArrayCall(Expression* expression, | |
| 8235 int arguments_count, | |
| 8236 HValue* function, | |
| 8237 Handle<AllocationSite> site) { | |
| 8238 Add<HCheckValue>(function, array_function()); | |
| 8239 | |
| 8240 if (IsCallArrayInlineable(arguments_count, site)) { | |
| 8241 BuildInlinedCallArray(expression, arguments_count, site); | |
| 8242 return; | |
| 8243 } | |
| 8244 | |
| 8245 HInstruction* call = PreProcessCall(New<HCallNewArray>( | |
| 8246 function, arguments_count + 1, site->GetElementsKind())); | |
| 8247 if (expression->IsCall()) { | |
| 8248 Drop(1); | |
| 8249 } | |
| 8250 ast_context()->ReturnInstruction(call, expression->id()); | |
| 8251 } | |
| 8252 | |
| 8253 | |
| 8254 bool HOptimizedGraphBuilder::TryHandleArrayCall(Call* expr, HValue* function) { | |
| 8255 if (!array_function().is_identical_to(expr->target())) { | |
| 8256 return false; | |
| 8257 } | |
| 8258 | |
| 8259 AllocationSiteInfo* site_info = | |
| 8260 reinterpret_cast<AllocationSiteInfo*>(expr->extra_info()); | |
| 8261 if (site_info == NULL) return false; | |
| 8262 Handle<AllocationSite> site = site_info->allocation_site(); | |
| 8263 if (site.is_null()) return false; | |
| 8264 | |
| 8265 BuildArrayCall(expr, | |
| 8266 expr->arguments()->length(), | |
| 8267 function, | |
| 8268 site); | |
| 8269 return true; | |
| 8270 } | |
| 8271 | |
| 8272 | |
| 8273 bool HOptimizedGraphBuilder::TryHandleArrayCallNew(CallNew* expr, | |
| 8274 HValue* function) { | |
| 8275 if (!array_function().is_identical_to(expr->target())) { | |
| 8276 return false; | |
| 8277 } | |
| 8278 | |
| 8279 BuildArrayCall(expr, | |
| 8280 expr->arguments()->length(), | |
| 8281 function, | |
| 8282 expr->allocation_site()); | |
| 8283 return true; | |
| 8284 } | |
| 8285 | |
| 8286 | |
| 8235 void HOptimizedGraphBuilder::VisitCall(Call* expr) { | 8287 void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
| 8236 ASSERT(!HasStackOverflow()); | 8288 ASSERT(!HasStackOverflow()); |
| 8237 ASSERT(current_block() != NULL); | 8289 ASSERT(current_block() != NULL); |
| 8238 ASSERT(current_block()->HasPredecessor()); | 8290 ASSERT(current_block()->HasPredecessor()); |
| 8239 Expression* callee = expr->expression(); | 8291 Expression* callee = expr->expression(); |
| 8240 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 8292 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
| 8241 HInstruction* call = NULL; | 8293 HInstruction* call = NULL; |
| 8242 | 8294 |
| 8243 Property* prop = callee->AsProperty(); | 8295 Property* prop = callee->AsProperty(); |
| 8244 if (prop != NULL) { | 8296 if (prop != NULL) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8319 } else { | 8371 } else { |
| 8320 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 8372 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 8321 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { | 8373 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { |
| 8322 return Bailout(kPossibleDirectCallToEval); | 8374 return Bailout(kPossibleDirectCallToEval); |
| 8323 } | 8375 } |
| 8324 | 8376 |
| 8325 // The function is on the stack in the unoptimized code during | 8377 // The function is on the stack in the unoptimized code during |
| 8326 // evaluation of the arguments. | 8378 // evaluation of the arguments. |
| 8327 CHECK_ALIVE(VisitForValue(expr->expression())); | 8379 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 8328 HValue* function = Top(); | 8380 HValue* function = Top(); |
| 8329 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); | 8381 if (expr->global_call()) { |
| 8330 if (global_call) { | |
| 8331 Variable* var = proxy->var(); | 8382 Variable* var = proxy->var(); |
| 8332 bool known_global_function = false; | 8383 bool known_global_function = false; |
| 8333 // If there is a global property cell for the name at compile time and | 8384 // If there is a global property cell for the name at compile time and |
| 8334 // access check is not enabled we assume that the function will not change | 8385 // access check is not enabled we assume that the function will not change |
| 8335 // and generate optimized code for calling the function. | 8386 // and generate optimized code for calling the function. |
| 8336 LookupResult lookup(isolate()); | 8387 LookupResult lookup(isolate()); |
| 8337 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, LOAD); | 8388 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, LOAD); |
| 8338 if (type == kUseCell && | 8389 if (type == kUseCell && |
| 8339 !current_info()->global_object()->IsAccessCheckNeeded()) { | 8390 !current_info()->global_object()->IsAccessCheckNeeded()) { |
| 8340 Handle<GlobalObject> global(current_info()->global_object()); | 8391 Handle<GlobalObject> global(current_info()->global_object()); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 8354 | 8405 |
| 8355 if (TryInlineBuiltinFunctionCall(expr)) { | 8406 if (TryInlineBuiltinFunctionCall(expr)) { |
| 8356 if (FLAG_trace_inlining) { | 8407 if (FLAG_trace_inlining) { |
| 8357 PrintF("Inlining builtin "); | 8408 PrintF("Inlining builtin "); |
| 8358 expr->target()->ShortPrint(); | 8409 expr->target()->ShortPrint(); |
| 8359 PrintF("\n"); | 8410 PrintF("\n"); |
| 8360 } | 8411 } |
| 8361 return; | 8412 return; |
| 8362 } | 8413 } |
| 8363 if (TryInlineApiFunctionCall(expr, receiver)) return; | 8414 if (TryInlineApiFunctionCall(expr, receiver)) return; |
| 8415 if (TryHandleArrayCall(expr, function)) return; | |
| 8364 if (TryInlineCall(expr)) return; | 8416 if (TryInlineCall(expr)) return; |
| 8365 | 8417 |
| 8366 PushArgumentsFromEnvironment(argument_count); | 8418 PushArgumentsFromEnvironment(argument_count); |
| 8367 call = BuildCallConstantFunction(expr->target(), argument_count); | 8419 call = BuildCallConstantFunction(expr->target(), argument_count); |
| 8368 } else { | 8420 } else { |
| 8369 Push(graph()->GetConstantUndefined()); | 8421 Push(graph()->GetConstantUndefined()); |
| 8370 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8422 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 8371 PushArgumentsFromEnvironment(argument_count); | 8423 PushArgumentsFromEnvironment(argument_count); |
| 8372 call = New<HCallFunction>(function, argument_count); | 8424 call = New<HCallFunction>(function, argument_count); |
| 8373 } | 8425 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 8403 PushArgumentsFromEnvironment(argument_count); | 8455 PushArgumentsFromEnvironment(argument_count); |
| 8404 call = New<HCallFunction>(function, argument_count); | 8456 call = New<HCallFunction>(function, argument_count); |
| 8405 } | 8457 } |
| 8406 } | 8458 } |
| 8407 | 8459 |
| 8408 Drop(1); // Drop the function. | 8460 Drop(1); // Drop the function. |
| 8409 return ast_context()->ReturnInstruction(call, expr->id()); | 8461 return ast_context()->ReturnInstruction(call, expr->id()); |
| 8410 } | 8462 } |
| 8411 | 8463 |
| 8412 | 8464 |
| 8413 void HOptimizedGraphBuilder::BuildInlinedCallNewArray(CallNew* expr) { | 8465 void HOptimizedGraphBuilder::BuildInlinedCallArray( |
| 8466 Expression* expression, | |
| 8467 int argument_count, | |
| 8468 Handle<AllocationSite> site) { | |
| 8469 ASSERT(!site.is_null()); | |
| 8414 NoObservableSideEffectsScope no_effects(this); | 8470 NoObservableSideEffectsScope no_effects(this); |
| 8415 | 8471 |
| 8416 int argument_count = expr->arguments()->length(); | |
| 8417 // We should at least have the constructor on the expression stack. | 8472 // We should at least have the constructor on the expression stack. |
| 8418 HValue* constructor = environment()->ExpressionStackAt(argument_count); | 8473 HValue* constructor = environment()->ExpressionStackAt(argument_count); |
| 8419 | 8474 |
| 8420 ElementsKind kind = expr->elements_kind(); | |
| 8421 Handle<AllocationSite> site = expr->allocation_site(); | |
| 8422 ASSERT(!site.is_null()); | |
| 8423 | |
| 8424 // Register on the site for deoptimization if the transition feedback changes. | 8475 // Register on the site for deoptimization if the transition feedback changes. |
| 8425 AllocationSite::AddDependentCompilationInfo( | 8476 AllocationSite::AddDependentCompilationInfo( |
| 8426 site, AllocationSite::TRANSITIONS, top_info()); | 8477 site, AllocationSite::TRANSITIONS, top_info()); |
| 8478 ElementsKind kind = site->GetElementsKind(); | |
| 8427 HInstruction* site_instruction = Add<HConstant>(site); | 8479 HInstruction* site_instruction = Add<HConstant>(site); |
| 8428 | 8480 |
| 8429 // In the single constant argument case, we may have to adjust elements kind | 8481 // In the single constant argument case, we may have to adjust elements kind |
| 8430 // to avoid creating a packed non-empty array. | 8482 // to avoid creating a packed non-empty array. |
| 8431 if (argument_count == 1 && !IsHoleyElementsKind(kind)) { | 8483 if (argument_count == 1 && !IsHoleyElementsKind(kind)) { |
| 8432 HValue* argument = environment()->Top(); | 8484 HValue* argument = environment()->Top(); |
| 8433 if (argument->IsConstant()) { | 8485 if (argument->IsConstant()) { |
| 8434 HConstant* constant_argument = HConstant::cast(argument); | 8486 HConstant* constant_argument = HConstant::cast(argument); |
| 8435 ASSERT(constant_argument->HasSmiValue()); | 8487 ASSERT(constant_argument->HasSmiValue()); |
| 8436 int constant_array_size = constant_argument->Integer32Value(); | 8488 int constant_array_size = constant_argument->Integer32Value(); |
| 8437 if (constant_array_size != 0) { | 8489 if (constant_array_size != 0) { |
| 8438 kind = GetHoleyElementsKind(kind); | 8490 kind = GetHoleyElementsKind(kind); |
| 8439 } | 8491 } |
| 8440 } | 8492 } |
| 8441 } | 8493 } |
| 8442 | 8494 |
| 8443 // Build the array. | 8495 // Build the array. |
| 8444 JSArrayBuilder array_builder(this, | 8496 JSArrayBuilder array_builder(this, |
| 8445 kind, | 8497 kind, |
| 8446 site_instruction, | 8498 site_instruction, |
| 8447 constructor, | 8499 constructor, |
| 8448 DISABLE_ALLOCATION_SITES); | 8500 DISABLE_ALLOCATION_SITES); |
| 8449 HValue* new_object; | 8501 HValue* new_object = NULL; |
| 8450 if (argument_count == 0) { | 8502 if (argument_count == 0) { |
|
danno
2014/05/16 16:34:11
ASSERT(argument_count == 0); and remove the if.
mvstanton
2014/05/19 13:45:24
I do need to support the 1 argument case too thoug
| |
| 8451 new_object = array_builder.AllocateEmptyArray(); | 8503 new_object = array_builder.AllocateEmptyArray(); |
| 8452 } else if (argument_count == 1) { | 8504 } else if (argument_count == 1) { |
| 8453 HValue* argument = environment()->Top(); | 8505 HValue* argument = environment()->Top(); |
| 8454 new_object = BuildAllocateArrayFromLength(&array_builder, argument); | 8506 new_object = BuildAllocateArrayFromLength(&array_builder, argument); |
| 8455 } else { | 8507 } else { |
| 8456 HValue* length = Add<HConstant>(argument_count); | 8508 UNREACHABLE(); |
| 8457 // Smi arrays need to initialize array elements with the hole because | |
| 8458 // bailout could occur if the arguments don't fit in a smi. | |
| 8459 // | |
| 8460 // TODO(mvstanton): If all the arguments are constants in smi range, then | |
| 8461 // we could set fill_with_hole to false and save a few instructions. | |
| 8462 JSArrayBuilder::FillMode fill_mode = IsFastSmiElementsKind(kind) | |
| 8463 ? JSArrayBuilder::FILL_WITH_HOLE | |
| 8464 : JSArrayBuilder::DONT_FILL_WITH_HOLE; | |
| 8465 new_object = array_builder.AllocateArray(length, length, fill_mode); | |
| 8466 HValue* elements = array_builder.GetElementsLocation(); | |
| 8467 for (int i = 0; i < argument_count; i++) { | |
| 8468 HValue* value = environment()->ExpressionStackAt(argument_count - i - 1); | |
| 8469 HValue* constant_i = Add<HConstant>(i); | |
| 8470 Add<HStoreKeyed>(elements, constant_i, value, kind); | |
| 8471 } | |
| 8472 } | 8509 } |
| 8473 | 8510 |
| 8474 Drop(argument_count + 1); // drop constructor and args. | 8511 int args_to_drop = argument_count + (expression->IsCall() ? 2 : 1); |
| 8512 Drop(args_to_drop); | |
| 8475 ast_context()->ReturnValue(new_object); | 8513 ast_context()->ReturnValue(new_object); |
| 8476 } | 8514 } |
| 8477 | 8515 |
| 8478 | 8516 |
| 8479 // Checks whether allocation using the given constructor can be inlined. | 8517 // Checks whether allocation using the given constructor can be inlined. |
| 8480 static bool IsAllocationInlineable(Handle<JSFunction> constructor) { | 8518 static bool IsAllocationInlineable(Handle<JSFunction> constructor) { |
| 8481 return constructor->has_initial_map() && | 8519 return constructor->has_initial_map() && |
| 8482 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && | 8520 constructor->initial_map()->instance_type() == JS_OBJECT_TYPE && |
| 8483 constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize && | 8521 constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize && |
| 8484 constructor->initial_map()->InitialPropertiesLength() == 0; | 8522 constructor->initial_map()->InitialPropertiesLength() == 0; |
| 8485 } | 8523 } |
| 8486 | 8524 |
| 8487 | 8525 |
| 8488 bool HOptimizedGraphBuilder::IsCallNewArrayInlineable(CallNew* expr) { | 8526 bool HOptimizedGraphBuilder::IsCallArrayInlineable( |
| 8527 int argument_count, | |
| 8528 Handle<AllocationSite> site) { | |
| 8489 Handle<JSFunction> caller = current_info()->closure(); | 8529 Handle<JSFunction> caller = current_info()->closure(); |
| 8490 Handle<JSFunction> target(isolate()->native_context()->array_function(), | 8530 Handle<JSFunction> target = array_function(); |
| 8491 isolate()); | |
| 8492 int argument_count = expr->arguments()->length(); | |
| 8493 // We should have the function plus array arguments on the environment stack. | 8531 // We should have the function plus array arguments on the environment stack. |
| 8494 ASSERT(environment()->length() >= (argument_count + 1)); | 8532 ASSERT(environment()->length() >= (argument_count + 1)); |
| 8495 Handle<AllocationSite> site = expr->allocation_site(); | |
| 8496 ASSERT(!site.is_null()); | 8533 ASSERT(!site.is_null()); |
| 8497 | 8534 |
| 8498 bool inline_ok = false; | 8535 bool inline_ok = false; |
| 8499 if (site->CanInlineCall()) { | 8536 if (site->CanInlineCall()) { |
| 8500 // We also want to avoid inlining in certain 1 argument scenarios. | 8537 // We also want to avoid inlining in certain 1 argument scenarios. |
| 8501 if (argument_count == 1) { | 8538 if (argument_count == 1) { |
| 8502 HValue* argument = Top(); | 8539 HValue* argument = Top(); |
| 8503 if (argument->IsConstant()) { | 8540 if (argument->IsConstant()) { |
| 8504 // Do not inline if the constant length argument is not a smi or | 8541 // Do not inline if the constant length argument is not a smi or |
| 8505 // outside the valid range for a fast array. | 8542 // outside the valid range for unrolled loop initialization. |
| 8506 HConstant* constant_argument = HConstant::cast(argument); | 8543 HConstant* constant_argument = HConstant::cast(argument); |
| 8507 if (constant_argument->HasSmiValue()) { | 8544 if (constant_argument->HasSmiValue()) { |
| 8508 int value = constant_argument->Integer32Value(); | 8545 int value = constant_argument->Integer32Value(); |
| 8509 inline_ok = value >= 0 && | 8546 inline_ok = value >= 0 && value <= kLoopUnfoldLimit; |
| 8510 value < JSObject::kInitialMaxFastElementArray; | |
| 8511 if (!inline_ok) { | 8547 if (!inline_ok) { |
| 8512 TraceInline(target, caller, | 8548 TraceInline(target, caller, |
| 8513 "Length outside of valid array range"); | 8549 "Constant length outside of valid inlining range."); |
| 8514 } | 8550 } |
| 8515 } | 8551 } |
| 8516 } else { | 8552 } else { |
| 8517 inline_ok = true; | 8553 TraceInline(target, caller, |
| 8554 "Dont inline [new] Array(n) where n isn't constant."); | |
| 8518 } | 8555 } |
| 8556 } else if (argument_count == 0) { | |
| 8557 inline_ok = true; | |
| 8519 } else { | 8558 } else { |
| 8520 inline_ok = true; | 8559 TraceInline(target, caller, "Too many arguments to inline."); |
| 8521 } | 8560 } |
| 8522 } else { | 8561 } else { |
| 8523 TraceInline(target, caller, "AllocationSite requested no inlining."); | 8562 TraceInline(target, caller, "AllocationSite requested no inlining."); |
| 8524 } | 8563 } |
| 8525 | 8564 |
| 8526 if (inline_ok) { | 8565 if (inline_ok) { |
| 8527 TraceInline(target, caller, NULL); | 8566 TraceInline(target, caller, NULL); |
| 8528 } | 8567 } |
| 8529 return inline_ok; | 8568 return inline_ok; |
| 8530 } | 8569 } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8640 initial_map_value->DeleteAndReplaceWith(NULL); | 8679 initial_map_value->DeleteAndReplaceWith(NULL); |
| 8641 receiver->DeleteAndReplaceWith(NULL); | 8680 receiver->DeleteAndReplaceWith(NULL); |
| 8642 check->DeleteAndReplaceWith(NULL); | 8681 check->DeleteAndReplaceWith(NULL); |
| 8643 environment()->SetExpressionStackAt(receiver_index, function); | 8682 environment()->SetExpressionStackAt(receiver_index, function); |
| 8644 HInstruction* call = | 8683 HInstruction* call = |
| 8645 PreProcessCall(New<HCallNew>(function, argument_count)); | 8684 PreProcessCall(New<HCallNew>(function, argument_count)); |
| 8646 return ast_context()->ReturnInstruction(call, expr->id()); | 8685 return ast_context()->ReturnInstruction(call, expr->id()); |
| 8647 } else { | 8686 } else { |
| 8648 // The constructor function is both an operand to the instruction and an | 8687 // The constructor function is both an operand to the instruction and an |
| 8649 // argument to the construct call. | 8688 // argument to the construct call. |
| 8650 Handle<JSFunction> array_function( | 8689 if (TryHandleArrayCallNew(expr, function)) return; |
| 8651 isolate()->native_context()->array_function(), isolate()); | |
| 8652 bool use_call_new_array = expr->target().is_identical_to(array_function); | |
| 8653 if (use_call_new_array && IsCallNewArrayInlineable(expr)) { | |
| 8654 // Verify we are still calling the array function for our native context. | |
| 8655 Add<HCheckValue>(function, array_function); | |
| 8656 BuildInlinedCallNewArray(expr); | |
| 8657 return; | |
| 8658 } | |
| 8659 | 8690 |
| 8660 HBinaryCall* call; | 8691 HInstruction* call = |
| 8661 if (use_call_new_array) { | 8692 PreProcessCall(New<HCallNew>(function, argument_count)); |
| 8662 Add<HCheckValue>(function, array_function); | |
| 8663 call = New<HCallNewArray>(function, argument_count, | |
| 8664 expr->elements_kind()); | |
| 8665 } else { | |
| 8666 call = New<HCallNew>(function, argument_count); | |
| 8667 } | |
| 8668 PreProcessCall(call); | |
| 8669 return ast_context()->ReturnInstruction(call, expr->id()); | 8693 return ast_context()->ReturnInstruction(call, expr->id()); |
| 8670 } | 8694 } |
| 8671 } | 8695 } |
| 8672 | 8696 |
| 8673 | 8697 |
| 8674 // Support for generating inlined runtime functions. | 8698 // Support for generating inlined runtime functions. |
| 8675 | 8699 |
| 8676 // Lookup table for generators for runtime calls that are generated inline. | 8700 // Lookup table for generators for runtime calls that are generated inline. |
| 8677 // Elements of the table are member pointers to functions of | 8701 // Elements of the table are member pointers to functions of |
| 8678 // HOptimizedGraphBuilder. | 8702 // HOptimizedGraphBuilder. |
| (...skipping 3118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11797 if (ShouldProduceTraceOutput()) { | 11821 if (ShouldProduceTraceOutput()) { |
| 11798 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11822 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 11799 } | 11823 } |
| 11800 | 11824 |
| 11801 #ifdef DEBUG | 11825 #ifdef DEBUG |
| 11802 graph_->Verify(false); // No full verify. | 11826 graph_->Verify(false); // No full verify. |
| 11803 #endif | 11827 #endif |
| 11804 } | 11828 } |
| 11805 | 11829 |
| 11806 } } // namespace v8::internal | 11830 } } // namespace v8::internal |
| OLD | NEW |