| Index: src/crankshaft/hydrogen.cc
|
| diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc
|
| index 6868f5563ea4bef76fb023a0f193b538e1b124b7..9e934f0a13fcfe11eff106da036461d70efe6175 100644
|
| --- a/src/crankshaft/hydrogen.cc
|
| +++ b/src/crankshaft/hydrogen.cc
|
| @@ -8820,9 +8820,13 @@ bool HOptimizedGraphBuilder::TryInlineGetter(Handle<Object> getter,
|
| BailoutId ast_id,
|
| BailoutId return_id) {
|
| if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true;
|
| - return getter->IsJSFunction() &&
|
| - TryInline(Handle<JSFunction>::cast(getter), 0, NULL, ast_id, return_id,
|
| - GETTER_CALL_RETURN, TailCallMode::kDisallow);
|
| + if (getter->IsJSFunction()) {
|
| + Handle<JSFunction> getter_function = Handle<JSFunction>::cast(getter);
|
| + return TryInlineBuiltinGetterCall(getter_function, receiver_map, ast_id) ||
|
| + TryInline(getter_function, 0, NULL, ast_id, return_id,
|
| + GETTER_CALL_RETURN, TailCallMode::kDisallow);
|
| + }
|
| + return false;
|
| }
|
|
|
| bool HOptimizedGraphBuilder::TryInlineSetter(Handle<Object> setter,
|
| @@ -8914,9 +8918,62 @@ bool HOptimizedGraphBuilder::CanInlineArrayResizeOperation(
|
| !IsReadOnlyLengthDescriptor(receiver_map);
|
| }
|
|
|
| +bool HOptimizedGraphBuilder::TryInlineBuiltinGetterCall(
|
| + Handle<JSFunction> function, Handle<Map> receiver_map, BailoutId ast_id) {
|
| + if (!function->shared()->HasBuiltinFunctionId()) return false;
|
| + BuiltinFunctionId id = function->shared()->builtin_function_id();
|
| +
|
| + // Try to inline getter calls like DataView.prototype.byteLength/byteOffset
|
| + // as operations in the calling function.
|
| + switch (id) {
|
| + case kDataViewBuffer: {
|
| + if (!receiver_map->IsJSDataViewMap()) return false;
|
| + HObjectAccess access = HObjectAccess::ForMapAndOffset(
|
| + receiver_map, JSDataView::kBufferOffset);
|
| + HValue* object = Pop(); // receiver
|
| + HInstruction* result = New<HLoadNamedField>(object, object, access);
|
| + ast_context()->ReturnInstruction(result, ast_id);
|
| + return true;
|
| + }
|
| + case kDataViewByteLength:
|
| + case kDataViewByteOffset: {
|
| + if (!receiver_map->IsJSDataViewMap()) return false;
|
| + int offset = (id == kDataViewByteLength) ? JSDataView::kByteLengthOffset
|
| + : JSDataView::kByteOffsetOffset;
|
| + HObjectAccess access =
|
| + HObjectAccess::ForMapAndOffset(receiver_map, offset);
|
| + HValue* object = Pop(); // receiver
|
| + HValue* checked_object = Add<HCheckArrayBufferNotNeutered>(object);
|
| + HInstruction* result =
|
| + New<HLoadNamedField>(object, checked_object, access);
|
| + ast_context()->ReturnInstruction(result, ast_id);
|
| + return true;
|
| + }
|
| + case kTypedArrayByteLength:
|
| + case kTypedArrayByteOffset:
|
| + case kTypedArrayLength: {
|
| + if (!receiver_map->IsJSTypedArrayMap()) return false;
|
| + int offset = (id == kTypedArrayLength)
|
| + ? JSTypedArray::kLengthOffset
|
| + : (id == kTypedArrayByteLength)
|
| + ? JSTypedArray::kByteLengthOffset
|
| + : JSTypedArray::kByteOffsetOffset;
|
| + HObjectAccess access =
|
| + HObjectAccess::ForMapAndOffset(receiver_map, offset);
|
| + HValue* object = Pop(); // receiver
|
| + HValue* checked_object = Add<HCheckArrayBufferNotNeutered>(object);
|
| + HInstruction* result =
|
| + New<HLoadNamedField>(object, checked_object, access);
|
| + ast_context()->ReturnInstruction(result, ast_id);
|
| + return true;
|
| + }
|
| + default:
|
| + return false;
|
| + }
|
| +}
|
|
|
| bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
|
| - Call* expr, Handle<JSFunction> function, Handle<Map> receiver_map,
|
| + Handle<JSFunction> function, Handle<Map> receiver_map, BailoutId ast_id,
|
| int args_count_no_receiver) {
|
| if (!function->shared()->HasBuiltinFunctionId()) return false;
|
| BuiltinFunctionId id = function->shared()->builtin_function_id();
|
| @@ -8961,12 +9018,12 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
|
| HInstruction* char_code =
|
| BuildStringCharCodeAt(string, index);
|
| if (id == kStringCharCodeAt) {
|
| - ast_context()->ReturnInstruction(char_code, expr->id());
|
| + ast_context()->ReturnInstruction(char_code, ast_id);
|
| return true;
|
| }
|
| AddInstruction(char_code);
|
| HInstruction* result = NewUncasted<HStringCharFromCode>(char_code);
|
| - ast_context()->ReturnInstruction(result, expr->id());
|
| + ast_context()->ReturnInstruction(result, ast_id);
|
| return true;
|
| }
|
| break;
|
| @@ -8978,7 +9035,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
|
| argument, Representation::Integer32());
|
| argument->SetFlag(HValue::kTruncatingToInt32);
|
| HInstruction* result = NewUncasted<HStringCharFromCode>(argument);
|
| - ast_context()->ReturnInstruction(result, expr->id());
|
| + ast_context()->ReturnInstruction(result, ast_id);
|
| return true;
|
| }
|
| break;
|
| @@ -8996,7 +9053,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
|
| HValue* argument = Pop();
|
| Drop(2); // Receiver and function.
|
| HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id);
|
| - ast_context()->ReturnInstruction(op, expr->id());
|
| + ast_context()->ReturnInstruction(op, ast_id);
|
| return true;
|
| }
|
| break;
|
| @@ -9027,7 +9084,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
|
| if (result == NULL) {
|
| result = NewUncasted<HPower>(left, right);
|
| }
|
| - ast_context()->ReturnInstruction(result, expr->id());
|
| + ast_context()->ReturnInstruction(result, ast_id);
|
| return true;
|
| }
|
| break;
|
| @@ -9040,7 +9097,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
|
| HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin
|
| : HMathMinMax::kMathMax;
|
| HInstruction* result = NewUncasted<HMathMinMax>(left, right, op);
|
| - ast_context()->ReturnInstruction(result, expr->id());
|
| + ast_context()->ReturnInstruction(result, ast_id);
|
| return true;
|
| }
|
| break;
|
| @@ -9051,7 +9108,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
|
| Drop(2); // Receiver and function.
|
| HInstruction* result =
|
| HMul::NewImul(isolate(), zone(), context(), left, right);
|
| - ast_context()->ReturnInstruction(result, expr->id());
|
| + ast_context()->ReturnInstruction(result, ast_id);
|
| return true;
|
| }
|
| break;
|
| @@ -9107,7 +9164,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
|
| length_checker.End();
|
| }
|
| result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top();
|
| - Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
|
| + Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
|
| if (!ast_context()->IsEffect()) Drop(1);
|
|
|
| ast_context()->ReturnValue(result);
|
| @@ -9160,7 +9217,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
|
| STORE, NEVER_RETURN_HOLE, STORE_AND_GROW_NO_TRANSITION);
|
|
|
| if (!ast_context()->IsEffect()) Push(new_size);
|
| - Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
|
| + Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
|
| if (!ast_context()->IsEffect()) Drop(1);
|
| }
|
|
|
| @@ -9274,7 +9331,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
|
| if_lengthiszero.End();
|
| }
|
| result = ast_context()->IsEffect() ? graph()->GetConstant0() : Top();
|
| - Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
|
| + Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
|
| if (!ast_context()->IsEffect()) Drop(1);
|
| ast_context()->ReturnValue(result);
|
| return true;
|
| @@ -9311,7 +9368,7 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
|
| HValue* index = BuildArrayIndexOf(receiver, search_element, kind, mode);
|
|
|
| if (!ast_context()->IsEffect()) Push(index);
|
| - Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
|
| + Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
|
| if (!ast_context()->IsEffect()) Drop(1);
|
| ast_context()->ReturnValue(index);
|
| return true;
|
| @@ -9508,7 +9565,7 @@ void HOptimizedGraphBuilder::HandleIndirectCall(Call* expr, HValue* function,
|
| HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
|
| known_function =
|
| Handle<JSFunction>::cast(HConstant::cast(function)->handle(isolate()));
|
| - if (TryInlineBuiltinMethodCall(expr, known_function, Handle<Map>(),
|
| + if (TryInlineBuiltinMethodCall(known_function, Handle<Map>(), expr->id(),
|
| args_count_no_receiver)) {
|
| if (FLAG_trace_inlining) {
|
| PrintF("Inlining builtin ");
|
| @@ -9909,7 +9966,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
|
| CHECK_ALIVE(VisitExpressions(expr->arguments()));
|
|
|
| Handle<Map> map = maps->length() == 1 ? maps->first() : Handle<Map>();
|
| - if (TryInlineBuiltinMethodCall(expr, known_function, map,
|
| + if (TryInlineBuiltinMethodCall(known_function, map, expr->id(),
|
| expr->arguments()->length())) {
|
| if (FLAG_trace_inlining) {
|
| PrintF("Inlining builtin ");
|
|
|