Revision: 20338
Author:   [email protected]
Date:     Fri Mar 28 15:25:24 2014 UTC
Log:      Inline internal getters for typed arrays & friends.

[email protected], [email protected]

Committed: https://code.google.com/p/v8/source/detail?r=20330

Review URL: https://codereview.chromium.org/212603014
http://code.google.com/p/v8/source/detail?r=20338

Modified:
 /branches/bleeding_edge/src/arraybuffer.js
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h
 /branches/bleeding_edge/src/spaces.cc
 /branches/bleeding_edge/src/typedarray.js
 /branches/bleeding_edge/test/cctest/test-api.cc
 /branches/bleeding_edge/test/mjsunit/harmony/typedarrays.js

=======================================
--- /branches/bleeding_edge/src/arraybuffer.js  Fri Mar 28 13:33:50 2014 UTC
+++ /branches/bleeding_edge/src/arraybuffer.js  Fri Mar 28 15:25:24 2014 UTC
@@ -45,7 +45,7 @@
     throw MakeTypeError('incompatible_method_receiver',
                         ['ArrayBuffer.prototype.byteLength', this]);
   }
-  return %ArrayBufferGetByteLength(this);
+  return %_ArrayBufferGetByteLength(this);
 }

 // ES6 Draft 15.13.5.5.3
@@ -60,7 +60,7 @@
     end = TO_INTEGER(end);
   }
   var first;
-  var byte_length = %ArrayBufferGetByteLength(this);
+  var byte_length = %_ArrayBufferGetByteLength(this);
   if (relativeStart < 0) {
     first = MathMax(byte_length + relativeStart, 0);
   } else {
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Fri Mar 28 13:33:50 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri Mar 28 15:25:24 2014 UTC
@@ -6024,6 +6024,11 @@
     return HObjectAccess::ForObservableJSObjectOffset(
         JSArrayBuffer::kBackingStoreOffset, Representation::External());
   }
+
+  static HObjectAccess ForJSArrayBufferByteLength() {
+    return HObjectAccess::ForObservableJSObjectOffset(
+        JSArrayBuffer::kByteLengthOffset, Representation::Tagged());
+  }

   static HObjectAccess ForExternalArrayExternalPointer() {
     return HObjectAccess::ForObservableJSObjectOffset(
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Fri Mar 28 13:33:50 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc     Fri Mar 28 15:25:24 2014 UTC
@@ -8728,6 +8728,58 @@
         FLAG_typed_array_max_size_in_heap));
   return ast_context()->ReturnInstruction(result, expr->id());
 }
+
+
+void HOptimizedGraphBuilder::GenerateArrayBufferGetByteLength(
+    CallRuntime* expr) {
+  ASSERT(expr->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
+  HValue* buffer = Pop();
+  HInstruction* result = New<HLoadNamedField>(
+    buffer,
+    static_cast<HValue*>(NULL),
+    HObjectAccess::ForJSArrayBufferByteLength());
+  return ast_context()->ReturnInstruction(result, expr->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength(
+    CallRuntime* expr) {
+  ASSERT(expr->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
+  HValue* buffer = Pop();
+  HInstruction* result = New<HLoadNamedField>(
+    buffer,
+    static_cast<HValue*>(NULL),
+    HObjectAccess::ForJSArrayBufferViewByteLength());
+  return ast_context()->ReturnInstruction(result, expr->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset(
+    CallRuntime* expr) {
+  ASSERT(expr->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
+  HValue* buffer = Pop();
+  HInstruction* result = New<HLoadNamedField>(
+    buffer,
+    static_cast<HValue*>(NULL),
+    HObjectAccess::ForJSArrayBufferViewByteOffset());
+  return ast_context()->ReturnInstruction(result, expr->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateTypedArrayGetLength(
+    CallRuntime* expr) {
+  ASSERT(expr->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
+  HValue* buffer = Pop();
+  HInstruction* result = New<HLoadNamedField>(
+    buffer,
+    static_cast<HValue*>(NULL),
+    HObjectAccess::ForJSTypedArrayLength());
+  return ast_context()->ReturnInstruction(result, expr->id());
+}


 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Fri Mar 28 13:33:50 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc      Fri Mar 28 15:25:24 2014 UTC
@@ -1132,33 +1132,26 @@
 }


-#define TYPED_ARRAY_GETTER(getter, accessor) \
- RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayGet##getter) { \
+#define BUFFER_VIEW_GETTER(Type, getter, accessor) \
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_##Type##Get##getter) { \ HandleScope scope(isolate); \ ASSERT(args.length() == 1); \ - CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0); \ - if (!holder->IsJSTypedArray()) \ - return isolate->Throw(*isolate->factory()->NewTypeError( \ - "not_typed_array", HandleVector<Object>(NULL, 0))); \ - Handle<JSTypedArray> typed_array(JSTypedArray::cast(*holder)); \ - return typed_array->accessor(); \ + CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0); \ + return holder->accessor(); \
   }

-TYPED_ARRAY_GETTER(ByteLength, byte_length)
-TYPED_ARRAY_GETTER(ByteOffset, byte_offset)
-TYPED_ARRAY_GETTER(Length, length)
+BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
+BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
+BUFFER_VIEW_GETTER(TypedArray, Length, length)
+BUFFER_VIEW_GETTER(DataView, Buffer, buffer)

-#undef TYPED_ARRAY_GETTER
+#undef BUFFER_VIEW_GETTER

 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayGetBuffer) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0);
-  if (!holder->IsJSTypedArray())
-    return isolate->Throw(*isolate->factory()->NewTypeError(
-        "not_typed_array", HandleVector<Object>(NULL, 0)));
-  Handle<JSTypedArray> typed_array(JSTypedArray::cast(*holder));
-  return *typed_array->GetBuffer();
+  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
+  return *holder->GetBuffer();
 }


@@ -1271,30 +1264,6 @@

   return isolate->heap()->undefined_value();
 }
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetBuffer) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
-  return data_view->buffer();
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteOffset) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
-  return data_view->byte_offset();
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteLength) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
-  return data_view->byte_length();
-}


 inline static bool NeedToFlipBytes(bool is_little_endian) {
=======================================
--- /branches/bleeding_edge/src/runtime.h       Fri Mar 28 13:33:50 2014 UTC
+++ /branches/bleeding_edge/src/runtime.h       Fri Mar 28 15:25:24 2014 UTC
@@ -328,21 +328,15 @@
   \
   /* Harmony typed arrays */ \
   F(ArrayBufferInitialize, 2, 1)\
-  F(ArrayBufferGetByteLength, 1, 1)\
   F(ArrayBufferSliceImpl, 3, 1) \
   F(ArrayBufferIsView, 1, 1) \
   F(ArrayBufferNeuter, 1, 1) \
   \
   F(TypedArrayInitializeFromArrayLike, 4, 1) \
   F(TypedArrayGetBuffer, 1, 1) \
-  F(TypedArrayGetByteLength, 1, 1) \
-  F(TypedArrayGetByteOffset, 1, 1) \
-  F(TypedArrayGetLength, 1, 1) \
   F(TypedArraySetFastCases, 3, 1) \
   \
   F(DataViewGetBuffer, 1, 1) \
-  F(DataViewGetByteLength, 1, 1) \
-  F(DataViewGetByteOffset, 1, 1) \
   F(DataViewGetInt8, 3, 1) \
   F(DataViewGetUint8, 3, 1) \
   F(DataViewGetInt16, 3, 1) \
@@ -690,13 +684,17 @@
// Entries have the form F(name, number of arguments, number of return values).
 #define INLINE_OPTIMIZED_FUNCTION_LIST(F) \
/* Typed Arrays */ \ - F(ConstructDouble, 2, 1) \ F(TypedArrayInitialize, 5, 1) \ F(DataViewInitialize, 4, 1) \ F(MaxSmi, 0, 1) \ F(TypedArrayMaxSizeInHeap, 0, 1) \
-  \
+ F(ArrayBufferViewGetByteLength, 1, 1) \ + F(ArrayBufferViewGetByteOffset, 1, 1) \ + F(TypedArrayGetLength, 1, 1) \ + /* ArrayBuffer */ \ + F(ArrayBufferGetByteLength, 1, 1) \ /* Maths */ \ + F(ConstructDouble, 2, 1) \ F(DoubleHi, 1, 1) \ F(DoubleLo, 1, 1) \ F(MathSqrt, 1, 1) \
=======================================
--- /branches/bleeding_edge/src/spaces.cc       Fri Mar 28 13:33:50 2014 UTC
+++ /branches/bleeding_edge/src/spaces.cc       Fri Mar 28 15:25:24 2014 UTC
@@ -1051,7 +1051,7 @@
   int size = 0;
   switch (identity()) {
     case OLD_POINTER_SPACE:
-      size = 72 * kPointerSize * KB;
+      size = 96 * kPointerSize * KB;
       break;
     case OLD_DATA_SPACE:
       size = 192 * KB;
=======================================
--- /branches/bleeding_edge/src/typedarray.js   Fri Mar 28 13:33:50 2014 UTC
+++ /branches/bleeding_edge/src/typedarray.js   Fri Mar 28 15:25:24 2014 UTC
@@ -57,7 +57,7 @@
         length = ToPositiveInteger(length, "invalid_typed_array_length");
     }

-    var bufferByteLength = %ArrayBufferGetByteLength(buffer);
+    var bufferByteLength = %_ArrayBufferGetByteLength(buffer);
     var offset;
     if (IS_UNDEFINED(byteOffset)) {
       offset = 0;
@@ -125,7 +125,6 @@
   }

   function NAMEConstructor(arg1, arg2, arg3) {
-
     if (%_IsConstructCall()) {
       if (IS_ARRAYBUFFER(arg1)) {
         NAMEConstructByArrayBuffer(this, arg1, arg2, arg3);
@@ -139,34 +138,52 @@
       throw MakeTypeError("constructor_not_function", ["NAME"])
     }
   }
-endmacro

-TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR)
+  function NAME_GetBuffer() {
+    if (!(%_ClassOf(this) === 'NAME')) {
+      throw MakeTypeError('incompatible_method_receiver',
+                          ["NAME.buffer", this]);
+    }
+    return %TypedArrayGetBuffer(this);
+  }

-function TypedArrayGetBuffer() {
-  return %TypedArrayGetBuffer(this);
-}
+  function NAME_GetByteLength() {
+    if (!(%_ClassOf(this) === 'NAME')) {
+      throw MakeTypeError('incompatible_method_receiver',
+                          ["NAME.byteLength", this]);
+    }
+    return %_ArrayBufferViewGetByteLength(this);
+  }

-function TypedArrayGetByteLength() {
-  return %TypedArrayGetByteLength(this);
-}
+  function NAME_GetByteOffset() {
+    if (!(%_ClassOf(this) === 'NAME')) {
+      throw MakeTypeError('incompatible_method_receiver',
+                          ["NAME.byteOffset", this]);
+    }
+    return %_ArrayBufferViewGetByteOffset(this);
+  }

-function TypedArrayGetByteOffset() {
-  return %TypedArrayGetByteOffset(this);
-}
+  function NAME_GetLength() {
+    if (!(%_ClassOf(this) === 'NAME')) {
+      throw MakeTypeError('incompatible_method_receiver',
+                          ["NAME.length", this]);
+    }
+    return %_TypedArrayGetLength(this);
+  }

-function TypedArrayGetLength() {
-  return %TypedArrayGetLength(this);
-}
+  var $NAME = global.NAME;

-function CreateSubArray(elementSize, constructor) {
-  return function(begin, end) {
+  function NAMESubArray(begin, end) {
+    if (!(%_ClassOf(this) === 'NAME')) {
+      throw MakeTypeError('incompatible_method_receiver',
+                          ["NAME.subarray", this]);
+    }
     var beginInt = TO_INTEGER(begin);
     if (!IS_UNDEFINED(end)) {
       end = TO_INTEGER(end);
     }

-    var srcLength = %TypedArrayGetLength(this);
+    var srcLength = %_TypedArrayGetLength(this);
     if (beginInt < 0) {
       beginInt = MathMax(0, srcLength + beginInt);
     } else {
@@ -184,11 +201,14 @@
     }
     var newLength = endInt - beginInt;
     var beginByteOffset =
-        %TypedArrayGetByteOffset(this) + beginInt * elementSize;
-    return new constructor(%TypedArrayGetBuffer(this),
-                           beginByteOffset, newLength);
+        %_ArrayBufferViewGetByteOffset(this) + beginInt * ELEMENT_SIZE;
+    return new $NAME(%TypedArrayGetBuffer(this),
+                     beginByteOffset, newLength);
   }
-}
+endmacro
+
+TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR)
+

 function TypedArraySetFromArrayLike(target, source, sourceLength, offset) {
   if (offset > 0) {
@@ -296,34 +316,34 @@

 // -------------------------------------------------------------------

-function SetupTypedArray(constructor, fun, elementSize) {
+function SetupTypedArrays() {
+macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
   %CheckIsBootstrapping();
-  %SetCode(constructor, fun);
-  %FunctionSetPrototype(constructor, new $Object());
+  %SetCode(global.NAME, NAMEConstructor);
+  %FunctionSetPrototype(global.NAME, new $Object());

-  %SetProperty(constructor, "BYTES_PER_ELEMENT", elementSize,
+  %SetProperty(global.NAME, "BYTES_PER_ELEMENT", ELEMENT_SIZE,
                READ_ONLY | DONT_ENUM | DONT_DELETE);
-  %SetProperty(constructor.prototype,
-               "constructor", constructor, DONT_ENUM);
-  %SetProperty(constructor.prototype,
-               "BYTES_PER_ELEMENT", elementSize,
+  %SetProperty(global.NAME.prototype,
+               "constructor", global.NAME, DONT_ENUM);
+  %SetProperty(global.NAME.prototype,
+               "BYTES_PER_ELEMENT", ELEMENT_SIZE,
                READ_ONLY | DONT_ENUM | DONT_DELETE);
-  InstallGetter(constructor.prototype, "buffer", TypedArrayGetBuffer);
- InstallGetter(constructor.prototype, "byteOffset", TypedArrayGetByteOffset); - InstallGetter(constructor.prototype, "byteLength", TypedArrayGetByteLength);
-  InstallGetter(constructor.prototype, "length", TypedArrayGetLength);
+  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);

-  InstallFunctions(constructor.prototype, DONT_ENUM, $Array(
-        "subarray", CreateSubArray(elementSize, constructor),
+  InstallFunctions(global.NAME.prototype, DONT_ENUM, $Array(
+        "subarray", NAMESubArray,
         "set", TypedArraySet
   ));
-}
-
-macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
-  SetupTypedArray (global.NAME, NAMEConstructor, ELEMENT_SIZE);
 endmacro

 TYPED_ARRAYS(SETUP_TYPED_ARRAY)
+}
+
+SetupTypedArrays();

 // --------------------------- DataView -----------------------------

@@ -341,7 +361,7 @@
         byteLength = TO_INTEGER(byteLength);
     }

-    var bufferByteLength = %ArrayBufferGetByteLength(buffer);
+    var bufferByteLength = %_ArrayBufferGetByteLength(buffer);

     var offset = IS_UNDEFINED(byteOffset) ?  0 : byteOffset;
     if (offset > bufferByteLength) {
@@ -373,7 +393,7 @@
     throw MakeTypeError('incompatible_method_receiver',
                         ['DataView.byteOffset', this]);
   }
-  return %DataViewGetByteOffset(this);
+  return %_ArrayBufferViewGetByteOffset(this);
 }

 function DataViewGetByteLength() {
@@ -381,7 +401,7 @@
     throw MakeTypeError('incompatible_method_receiver',
                         ['DataView.byteLength', this]);
   }
-  return %DataViewGetByteLength(this);
+  return %_ArrayBufferViewGetByteLength(this);
 }

 macro DATA_VIEW_TYPES(FUNCTION)
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Fri Mar 28 14:16:11 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-api.cc Fri Mar 28 15:25:24 2014 UTC
@@ -4052,7 +4052,7 @@

   v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
       iso)->heap();
-  heap->CollectGarbage(i::NEW_SPACE);
+  heap->CollectAllGarbage(i::Heap::kNoGCFlags);

   // All objects should be alive.
   CHECK_EQ(0, counter.NumberOfWeakCalls());
@@ -4084,7 +4084,7 @@
         v8_str("x"), Local<Value>::New(iso, g1s1.handle));
   }

-  heap->CollectGarbage(i::NEW_SPACE);
+  heap->CollectAllGarbage(i::Heap::kNoGCFlags);

   // All objects should be gone. 7 global handles in total.
   CHECK_EQ(7, counter.NumberOfWeakCalls());
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/typedarrays.js Fri Mar 28 13:33:50 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/harmony/typedarrays.js Fri Mar 28 15:25:24 2014 UTC
@@ -310,6 +310,11 @@

   SubarrayTestCase(constructor, item, 10,90,        100, 90);
   SubarrayTestCase(constructor, item, 10,90,        100, -10);
+
+  var method = constructor.prototype.subarray;
+  method.call(new constructor(100), 0, 100);
+  var o = {};
+  assertThrows(function() { method.call(o, 0, 100); }, TypeError);
 }

 TestSubArray(Uint8Array, 0xFF);

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to