Commit 87eef732 authored by verwaest's avatar verwaest Committed by Commit bot

Fix speedup of typedarray-length loading in the ICs as well as Crankshaft

BUG=

Review URL: https://codereview.chromium.org/1034393002

Cr-Commit-Position: refs/heads/master@{#27519}
parent 97981d94
......@@ -79,6 +79,14 @@ bool Accessors::IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
CheckForName(name, isolate->factory()->length_string(),
JSArray::kLengthOffset, object_offset);
case JS_TYPED_ARRAY_TYPE:
// %TypedArray%.prototype is non-configurable, and so are the following
// named properties on %TypedArray%.prototype, so we can directly inline
// the field-load for typed array maps that still use their
// %TypedArray%.prototype.
if (JSFunction::cast(map->GetConstructor())->prototype() !=
map->prototype()) {
return false;
}
return
CheckForName(name, isolate->factory()->length_string(),
JSTypedArray::kLengthOffset, object_offset) ||
......
......@@ -1219,16 +1219,13 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
case LookupIterator::ACCESSOR: {
// Use simple field loads for some well-known callback properties.
if (receiver_is_holder) {
DCHECK(receiver->IsJSObject());
Handle<JSObject> js_receiver = Handle<JSObject>::cast(receiver);
int object_offset;
if (Accessors::IsJSObjectFieldAccessor(map, lookup->name(),
&object_offset)) {
FieldIndex index =
FieldIndex::ForInObjectOffset(object_offset, js_receiver->map());
return SimpleFieldLoad(index);
}
// The method will only return true for absolute truths based on the
// receiver maps.
int object_offset;
if (Accessors::IsJSObjectFieldAccessor(map, lookup->name(),
&object_offset)) {
FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map);
return SimpleFieldLoad(index);
}
Handle<Object> accessors = lookup->GetAccessors();
......
......@@ -314,9 +314,12 @@ macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
"BYTES_PER_ELEMENT", ELEMENT_SIZE,
READ_ONLY | DONT_ENUM | DONT_DELETE);
InstallGetter(global.NAME.prototype, "buffer", NAME_GetBuffer);
InstallGetter(global.NAME.prototype, "byteOffset", NAME_GetByteOffset);
InstallGetter(global.NAME.prototype, "byteLength", NAME_GetByteLength);
InstallGetter(global.NAME.prototype, "length", NAME_GetLength);
InstallGetter(global.NAME.prototype, "byteOffset", NAME_GetByteOffset,
DONT_ENUM | DONT_DELETE);
InstallGetter(global.NAME.prototype, "byteLength", NAME_GetByteLength,
DONT_ENUM | DONT_DELETE);
InstallGetter(global.NAME.prototype, "length", NAME_GetLength,
DONT_ENUM | DONT_DELETE);
InstallGetter(global.NAME.prototype, symbolToStringTag,
TypedArrayGetToStringTag);
InstallFunctions(global.NAME.prototype, DONT_ENUM, $Array(
......
......@@ -44,10 +44,13 @@ function OverrideFunction(object, name, f) {
// Helper function to install a getter-only accessor property.
function InstallGetter(object, name, getter) {
function InstallGetter(object, name, getter, attributes) {
if (typeof attributes == "undefined") {
attributes = DONT_ENUM;
}
%FunctionSetName(getter, name);
%FunctionRemovePrototype(getter);
%DefineAccessorPropertyUnchecked(object, name, getter, null, DONT_ENUM);
%DefineAccessorPropertyUnchecked(object, name, getter, null, attributes);
%SetNativeFlag(getter);
}
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
var a = new Int32Array(100);
a.__proto__ = null;
function get(a) {
return a.length;
}
assertEquals(undefined, get(a));
assertEquals(undefined, get(a));
assertEquals(undefined, get(a));
%OptimizeFunctionOnNextCall(get);
assertEquals(undefined, get(a));
get = function(a) {
return a.byteLength;
}
assertEquals(undefined, get(a));
assertEquals(undefined, get(a));
assertEquals(undefined, get(a));
%OptimizeFunctionOnNextCall(get);
assertEquals(undefined, get(a));
get = function(a) {
return a.byteOffset;
}
assertEquals(undefined, get(a));
assertEquals(undefined, get(a));
assertEquals(undefined, get(a));
%OptimizeFunctionOnNextCall(get);
assertEquals(undefined, get(a));
(function() {
"use strict";
class MyTypedArray extends Int32Array {
get length() {
return "length";
}
}
a = new MyTypedArray();
get = function(a) {
return a.length;
}
assertEquals("length", get(a));
assertEquals("length", get(a));
assertEquals("length", get(a));
%OptimizeFunctionOnNextCall(get);
assertEquals("length", get(a));
a.__proto__ = null;
get = function(a) {
return a.length;
}
assertEquals(undefined, get(a));
assertEquals(undefined, get(a));
assertEquals(undefined, get(a));
%OptimizeFunctionOnNextCall(get);
assertEquals(undefined, get(a));
})();
// Ensure we cannot delete length, byteOffset, byteLength.
assertTrue(Int32Array.prototype.hasOwnProperty("length"));
assertTrue(Int32Array.prototype.hasOwnProperty("byteOffset"));
assertTrue(Int32Array.prototype.hasOwnProperty("byteLength"));
assertFalse(delete Int32Array.prototype.length);
assertFalse(delete Int32Array.prototype.byteOffset);
assertFalse(delete Int32Array.prototype.byteLength);
a = new Int32Array(100);
get = function(a) {
return a.length;
}
assertEquals(100, get(a));
assertEquals(100, get(a));
assertEquals(100, get(a));
%OptimizeFunctionOnNextCall(get);
assertEquals(100, get(a));
get = function(a) {
return a.byteLength;
}
assertEquals(400, get(a));
assertEquals(400, get(a));
assertEquals(400, get(a));
%OptimizeFunctionOnNextCall(get);
assertEquals(400, get(a));
get = function(a) {
return a.byteOffset;
}
assertEquals(0, get(a));
assertEquals(0, get(a));
assertEquals(0, get(a));
%OptimizeFunctionOnNextCall(get);
assertEquals(0, get(a));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment