mirror of https://github.com/lukechilds/node.git
Browse Source
PR-URL: https://github.com/nodejs/node/pull/6077 Reviewed-By: Trevor Norris <trev.norris@gmail.com>process-exit-stdio-flushing
21 changed files with 349 additions and 211 deletions
@ -1,142 +0,0 @@ |
|||||
// Copyright 2014 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.
|
|
||||
|
|
||||
#include "test/cctest/compiler/function-tester.h" |
|
||||
|
|
||||
namespace v8 { |
|
||||
namespace internal { |
|
||||
namespace compiler { |
|
||||
|
|
||||
template <typename U> |
|
||||
static void TypedArrayLoadHelper(const char* array_type) { |
|
||||
static const uint32_t kValues[] = { |
|
||||
0x00000000, 0x00000001, 0x00000023, 0x00000042, 0x12345678, 0x87654321, |
|
||||
0x0000003f, 0x0000007f, 0x00003fff, 0x00007fff, 0x3fffffff, 0x7fffffff, |
|
||||
0x000000ff, 0x00000080, 0x0000ffff, 0x00008000, 0xffffffff, 0x80000000}; |
|
||||
EmbeddedVector<char, 1024> values_buffer; |
|
||||
StringBuilder values_builder(values_buffer.start(), values_buffer.length()); |
|
||||
for (size_t i = 0; i < arraysize(kValues); ++i) { |
|
||||
values_builder.AddFormatted("a[%d] = 0x%08x;", i, kValues[i]); |
|
||||
} |
|
||||
|
|
||||
// Note that below source creates two different typed arrays with the same
|
|
||||
// elements kind to get coverage for both (on heap / with external backing
|
|
||||
// store) access patterns.
|
|
||||
const char* source = |
|
||||
"(function(a) {" |
|
||||
" var x = (a = new %sArray(%d)); %s;" |
|
||||
" var y = (a = new %sArray(%d)); %s; %%TypedArrayGetBuffer(y);" |
|
||||
" if (!%%HasFixed%sElements(x)) %%AbortJS('x');" |
|
||||
" if (!%%HasFixed%sElements(y)) %%AbortJS('y');" |
|
||||
" function f(a,b) {" |
|
||||
" a = a | 0; b = b | 0;" |
|
||||
" return x[a] + y[b];" |
|
||||
" }" |
|
||||
" return f;" |
|
||||
"})()"; |
|
||||
EmbeddedVector<char, 1024> source_buffer; |
|
||||
SNPrintF(source_buffer, source, array_type, arraysize(kValues), |
|
||||
values_buffer.start(), array_type, arraysize(kValues), |
|
||||
values_buffer.start(), array_type, array_type); |
|
||||
|
|
||||
FunctionTester T(source_buffer.start(), |
|
||||
CompilationInfo::kFunctionContextSpecializing | |
|
||||
CompilationInfo::kTypingEnabled); |
|
||||
for (size_t i = 0; i < arraysize(kValues); ++i) { |
|
||||
for (size_t j = 0; j < arraysize(kValues); ++j) { |
|
||||
volatile U value_a = static_cast<U>(kValues[i]); |
|
||||
volatile U value_b = static_cast<U>(kValues[j]); |
|
||||
double expected = |
|
||||
static_cast<double>(value_a) + static_cast<double>(value_b); |
|
||||
T.CheckCall(T.Val(expected), T.Val(static_cast<double>(i)), |
|
||||
T.Val(static_cast<double>(j))); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
TEST(TypedArrayLoad) { |
|
||||
FLAG_typed_array_max_size_in_heap = 256; |
|
||||
TypedArrayLoadHelper<int8_t>("Int8"); |
|
||||
TypedArrayLoadHelper<uint8_t>("Uint8"); |
|
||||
TypedArrayLoadHelper<int16_t>("Int16"); |
|
||||
TypedArrayLoadHelper<uint16_t>("Uint16"); |
|
||||
TypedArrayLoadHelper<int32_t>("Int32"); |
|
||||
TypedArrayLoadHelper<uint32_t>("Uint32"); |
|
||||
TypedArrayLoadHelper<float>("Float32"); |
|
||||
TypedArrayLoadHelper<double>("Float64"); |
|
||||
// TODO(mstarzinger): Add tests for ClampedUint8.
|
|
||||
} |
|
||||
|
|
||||
|
|
||||
template <typename U> |
|
||||
static void TypedArrayStoreHelper(const char* array_type) { |
|
||||
static const uint32_t kValues[] = { |
|
||||
0x00000000, 0x00000001, 0x00000023, 0x00000042, 0x12345678, 0x87654321, |
|
||||
0x0000003f, 0x0000007f, 0x00003fff, 0x00007fff, 0x3fffffff, 0x7fffffff, |
|
||||
0x000000ff, 0x00000080, 0x0000ffff, 0x00008000, 0xffffffff, 0x80000000}; |
|
||||
EmbeddedVector<char, 1024> values_buffer; |
|
||||
StringBuilder values_builder(values_buffer.start(), values_buffer.length()); |
|
||||
for (size_t i = 0; i < arraysize(kValues); ++i) { |
|
||||
values_builder.AddFormatted("a[%d] = 0x%08x;", i, kValues[i]); |
|
||||
} |
|
||||
|
|
||||
// Note that below source creates two different typed arrays with the same
|
|
||||
// elements kind to get coverage for both (on heap/with external backing
|
|
||||
// store) access patterns.
|
|
||||
const char* source = |
|
||||
"(function(a) {" |
|
||||
" var x = (a = new %sArray(%d)); %s;" |
|
||||
" var y = (a = new %sArray(%d)); %s; %%TypedArrayGetBuffer(y);" |
|
||||
" if (!%%HasFixed%sElements(x)) %%AbortJS('x');" |
|
||||
" if (!%%HasFixed%sElements(y)) %%AbortJS('y');" |
|
||||
" function f(a,b) {" |
|
||||
" a = a | 0; b = b | 0;" |
|
||||
" var t = x[a];" |
|
||||
" x[a] = y[b];" |
|
||||
" y[b] = t;" |
|
||||
" t = y[b];" |
|
||||
" y[b] = x[a];" |
|
||||
" x[a] = t;" |
|
||||
" return x[a] + y[b];" |
|
||||
" }" |
|
||||
" return f;" |
|
||||
"})()"; |
|
||||
EmbeddedVector<char, 2048> source_buffer; |
|
||||
SNPrintF(source_buffer, source, array_type, arraysize(kValues), |
|
||||
values_buffer.start(), array_type, arraysize(kValues), |
|
||||
values_buffer.start(), array_type, array_type); |
|
||||
|
|
||||
FunctionTester T(source_buffer.start(), |
|
||||
CompilationInfo::kFunctionContextSpecializing | |
|
||||
CompilationInfo::kTypingEnabled); |
|
||||
for (size_t i = 0; i < arraysize(kValues); ++i) { |
|
||||
for (size_t j = 0; j < arraysize(kValues); ++j) { |
|
||||
volatile U value_a = static_cast<U>(kValues[i]); |
|
||||
volatile U value_b = static_cast<U>(kValues[j]); |
|
||||
double expected = |
|
||||
static_cast<double>(value_a) + static_cast<double>(value_b); |
|
||||
T.CheckCall(T.Val(expected), T.Val(static_cast<double>(i)), |
|
||||
T.Val(static_cast<double>(j))); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
TEST(TypedArrayStore) { |
|
||||
FLAG_typed_array_max_size_in_heap = 256; |
|
||||
TypedArrayStoreHelper<int8_t>("Int8"); |
|
||||
TypedArrayStoreHelper<uint8_t>("Uint8"); |
|
||||
TypedArrayStoreHelper<int16_t>("Int16"); |
|
||||
TypedArrayStoreHelper<uint16_t>("Uint16"); |
|
||||
TypedArrayStoreHelper<int32_t>("Int32"); |
|
||||
TypedArrayStoreHelper<uint32_t>("Uint32"); |
|
||||
TypedArrayStoreHelper<float>("Float32"); |
|
||||
TypedArrayStoreHelper<double>("Float64"); |
|
||||
// TODO(mstarzinger): Add tests for ClampedUint8.
|
|
||||
} |
|
||||
|
|
||||
} // namespace compiler
|
|
||||
} // namespace internal
|
|
||||
} // namespace v8
|
|
@ -0,0 +1,76 @@ |
|||||
|
// Copyright 2016 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
|
||||
|
|
||||
|
function f(x, len) { |
||||
|
var distraction = []; |
||||
|
var result = new Array(25); |
||||
|
|
||||
|
// Create a bunch of double values with long live ranges.
|
||||
|
var d0 = x + 0.5; |
||||
|
var d1 = x + 1.5; |
||||
|
var d2 = x + 2.5; |
||||
|
var d3 = x + 3.5; |
||||
|
var d4 = x + 4.5; |
||||
|
var d5 = x + 5.5; |
||||
|
var d6 = x + 6.5; |
||||
|
var d7 = x + 7.5; |
||||
|
var d8 = x + 8.5; |
||||
|
var d9 = x + 9.5; |
||||
|
var d10 = x + 10.5; |
||||
|
var d11 = x + 11.5; |
||||
|
var d12 = x + 12.5; |
||||
|
var d13 = x + 13.5; |
||||
|
var d14 = x + 14.5; |
||||
|
var d15 = x + 15.5; |
||||
|
var d16 = x + 16.5; |
||||
|
var d17 = x + 17.5; |
||||
|
var d18 = x + 18.5; |
||||
|
var d19 = x + 19.5; |
||||
|
var d20 = x + 20.5; |
||||
|
var d21 = x + 21.5; |
||||
|
var d22 = x + 22.5; |
||||
|
var d23 = x + 23.5; |
||||
|
var d24 = x + 24.5; |
||||
|
|
||||
|
// Trigger a stub failure when the array grows too big.
|
||||
|
distraction[len] = 0; |
||||
|
|
||||
|
// Write the long-lived doubles to memory and verify them.
|
||||
|
result[0] = d0; |
||||
|
result[1] = d1; |
||||
|
result[2] = d2; |
||||
|
result[3] = d3; |
||||
|
result[4] = d4; |
||||
|
result[5] = d5; |
||||
|
result[6] = d6; |
||||
|
result[7] = d7; |
||||
|
result[8] = d8; |
||||
|
result[9] = d9; |
||||
|
result[10] = d10; |
||||
|
result[11] = d11; |
||||
|
result[12] = d12; |
||||
|
result[13] = d13; |
||||
|
result[14] = d14; |
||||
|
result[15] = d15; |
||||
|
result[16] = d16; |
||||
|
result[17] = d17; |
||||
|
result[18] = d18; |
||||
|
result[19] = d19; |
||||
|
result[20] = d20; |
||||
|
result[21] = d21; |
||||
|
result[22] = d22; |
||||
|
result[23] = d23; |
||||
|
result[24] = d24; |
||||
|
|
||||
|
for (var i = 0; i < result.length; i++) { |
||||
|
assertEquals(x + i + 0.5, result[i]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
f(0, 10); |
||||
|
f(0, 10); |
||||
|
%OptimizeFunctionOnNextCall(f); |
||||
|
f(0, 80000); |
@ -0,0 +1,20 @@ |
|||||
|
// Copyright 2016 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 boom = (function(stdlib, foreign, heap) { |
||||
|
"use asm"; |
||||
|
var MEM8 = new stdlib.Uint8Array(heap); |
||||
|
var MEM32 = new stdlib.Int32Array(heap); |
||||
|
function foo(i, j) { |
||||
|
j = MEM8[256]; |
||||
|
// This following value '10' determines the value of 'rax'
|
||||
|
MEM32[j >> 10] = 0xabcdefaa; |
||||
|
return MEM32[j >> 2] + j |
||||
|
} |
||||
|
return foo |
||||
|
})(this, 0, new ArrayBuffer(256)); |
||||
|
%OptimizeFunctionOnNextCall(boom); |
||||
|
boom(0, 0x1000); |
@ -0,0 +1,36 @@ |
|||||
|
// Copyright 2016 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: --expose-gc
|
||||
|
|
||||
|
array = new Array(10); |
||||
|
array[0] = 0.1; |
||||
|
// array[1] = THE_HOLE, reading through the prototype chain
|
||||
|
array[2] = 2.1; |
||||
|
array[3] = 3.1; |
||||
|
|
||||
|
var copy = array.slice(0, array.length); |
||||
|
|
||||
|
// Change the array's prototype.
|
||||
|
var proto = {}; |
||||
|
array.__proto__ = proto; |
||||
|
|
||||
|
// Define [1] on the prototype to alter the array during concatenation.
|
||||
|
Object.defineProperty( |
||||
|
proto, 1, { |
||||
|
get() { |
||||
|
// Alter the array.
|
||||
|
array.length = 1; |
||||
|
// Force gc to move the array.
|
||||
|
gc(); |
||||
|
return "value from proto"; |
||||
|
}, |
||||
|
set(new_value) { } |
||||
|
}); |
||||
|
|
||||
|
var concatted_array = Array.prototype.concat.call(array); |
||||
|
assertEquals(concatted_array[0], 0.1); |
||||
|
assertEquals(concatted_array[1], "value from proto"); |
||||
|
assertEquals(concatted_array[2], undefined); |
||||
|
assertEquals(concatted_array[3], undefined); |
@ -0,0 +1,35 @@ |
|||||
|
// Copyright 2016 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: --expose-gc
|
||||
|
|
||||
|
array = new Array(10); |
||||
|
array[0] = 0.1; |
||||
|
// array[1] = THE_HOLE, reading through the prototype chain
|
||||
|
array[2] = 2.1; |
||||
|
array[3] = 3.1; |
||||
|
|
||||
|
var copy = array.slice(0, array.length); |
||||
|
|
||||
|
// Use the defaul array prototype.
|
||||
|
var proto = array.__proto__; |
||||
|
|
||||
|
// Define [1] on the prototype to alter the array during concatenation.
|
||||
|
Object.defineProperty( |
||||
|
proto, 1, { |
||||
|
get() { |
||||
|
// Alter the array.
|
||||
|
array.length = 1; |
||||
|
// Force gc to move the array.
|
||||
|
gc(); |
||||
|
return "value from proto"; |
||||
|
}, |
||||
|
set(new_value) { } |
||||
|
}); |
||||
|
|
||||
|
var concatted_array = Array.prototype.concat.call(array); |
||||
|
assertEquals(concatted_array[0], 0.1); |
||||
|
assertEquals(concatted_array[1], "value from proto"); |
||||
|
assertEquals(concatted_array[2], undefined); |
||||
|
assertEquals(concatted_array[3], undefined); |
Loading…
Reference in new issue