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

Unified Diff: src/crankshaft/hydrogen.cc

Issue 2042013003: [builtins] Properly optimize TypedArray/DataView accessors. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address Yang's comments. Created 4 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | src/heap-symbols.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 ");
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | src/heap-symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698