OLD | NEW |
1 // Copyright 2007-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
11 // with the distribution. | 11 // with the distribution. |
12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
15 // | 15 // |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
| 28 #include <limits.h> |
| 29 |
28 #include "v8.h" | 30 #include "v8.h" |
29 | 31 |
30 #include "api.h" | 32 #include "api.h" |
31 #include "compilation-cache.h" | 33 #include "compilation-cache.h" |
32 #include "execution.h" | 34 #include "execution.h" |
33 #include "snapshot.h" | 35 #include "snapshot.h" |
34 #include "platform.h" | 36 #include "platform.h" |
35 #include "top.h" | 37 #include "top.h" |
| 38 #include "utils.h" |
36 #include "cctest.h" | 39 #include "cctest.h" |
37 | 40 |
38 static bool IsNaN(double x) { | 41 static bool IsNaN(double x) { |
39 #ifdef WIN32 | 42 #ifdef WIN32 |
40 return _isnan(x); | 43 return _isnan(x); |
41 #else | 44 #else |
42 return isnan(x); | 45 return isnan(x); |
43 #endif | 46 #endif |
44 } | 47 } |
45 | 48 |
(...skipping 7986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8032 CHECK_EQ(77, v8::Object::Cast(*result)->Get(v8_str("0"))->Int32Value()); | 8035 CHECK_EQ(77, v8::Object::Cast(*result)->Get(v8_str("0"))->Int32Value()); |
8033 CHECK_EQ(23, v8::Object::Cast(*result)->Get(v8_str("1"))->Int32Value()); | 8036 CHECK_EQ(23, v8::Object::Cast(*result)->Get(v8_str("1"))->Int32Value()); |
8034 | 8037 |
8035 result = CompileRun("pixels[1] = 23;"); | 8038 result = CompileRun("pixels[1] = 23;"); |
8036 CHECK_EQ(23, result->Int32Value()); | 8039 CHECK_EQ(23, result->Int32Value()); |
8037 | 8040 |
8038 free(pixel_data); | 8041 free(pixel_data); |
8039 } | 8042 } |
8040 | 8043 |
8041 | 8044 |
| 8045 template <class ExternalArrayClass, class ElementType> |
| 8046 static void ExternalArrayTestHelper(v8::ExternalArrayType array_type, |
| 8047 int64_t low, |
| 8048 int64_t high) { |
| 8049 v8::HandleScope scope; |
| 8050 LocalContext context; |
| 8051 const int kElementCount = 40; |
| 8052 int element_size = 0; |
| 8053 switch (array_type) { |
| 8054 case v8::kExternalByteArray: |
| 8055 case v8::kExternalUnsignedByteArray: |
| 8056 element_size = 1; |
| 8057 break; |
| 8058 case v8::kExternalShortArray: |
| 8059 case v8::kExternalUnsignedShortArray: |
| 8060 element_size = 2; |
| 8061 break; |
| 8062 case v8::kExternalIntArray: |
| 8063 case v8::kExternalUnsignedIntArray: |
| 8064 case v8::kExternalFloatArray: |
| 8065 element_size = 4; |
| 8066 break; |
| 8067 default: |
| 8068 UNREACHABLE(); |
| 8069 break; |
| 8070 } |
| 8071 ElementType* array_data = |
| 8072 static_cast<ElementType*>(malloc(kElementCount * element_size)); |
| 8073 i::Handle<ExternalArrayClass> array = |
| 8074 i::Handle<ExternalArrayClass>::cast( |
| 8075 i::Factory::NewExternalArray(kElementCount, array_type, array_data)); |
| 8076 i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. |
| 8077 for (int i = 0; i < kElementCount; i++) { |
| 8078 array->set(i, static_cast<ElementType>(i)); |
| 8079 } |
| 8080 i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. |
| 8081 for (int i = 0; i < kElementCount; i++) { |
| 8082 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array->get(i))); |
| 8083 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i])); |
| 8084 } |
| 8085 |
| 8086 v8::Handle<v8::Object> obj = v8::Object::New(); |
| 8087 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); |
| 8088 // Set the elements to be the external array. |
| 8089 obj->SetIndexedPropertiesToExternalArrayData(array_data, |
| 8090 array_type, |
| 8091 kElementCount); |
| 8092 CHECK_EQ(1, static_cast<int>(jsobj->GetElement(1)->Number())); |
| 8093 obj->Set(v8_str("field"), v8::Int32::New(1503)); |
| 8094 context->Global()->Set(v8_str("ext_array"), obj); |
| 8095 v8::Handle<v8::Value> result = CompileRun("ext_array.field"); |
| 8096 CHECK_EQ(1503, result->Int32Value()); |
| 8097 result = CompileRun("ext_array[1]"); |
| 8098 CHECK_EQ(1, result->Int32Value()); |
| 8099 |
| 8100 // Check pass through of assigned smis |
| 8101 result = CompileRun("var sum = 0;" |
| 8102 "for (var i = 0; i < 8; i++) {" |
| 8103 " sum += ext_array[i] = ext_array[i] = -i;" |
| 8104 "}" |
| 8105 "sum;"); |
| 8106 CHECK_EQ(-28, result->Int32Value()); |
| 8107 |
| 8108 // Check assigned smis |
| 8109 result = CompileRun("for (var i = 0; i < 8; i++) {" |
| 8110 " ext_array[i] = i;" |
| 8111 "}" |
| 8112 "var sum = 0;" |
| 8113 "for (var i = 0; i < 8; i++) {" |
| 8114 " sum += ext_array[i];" |
| 8115 "}" |
| 8116 "sum;"); |
| 8117 CHECK_EQ(28, result->Int32Value()); |
| 8118 |
| 8119 // Check assigned smis in reverse order |
| 8120 result = CompileRun("for (var i = 8; --i >= 0; ) {" |
| 8121 " ext_array[i] = i;" |
| 8122 "}" |
| 8123 "var sum = 0;" |
| 8124 "for (var i = 0; i < 8; i++) {" |
| 8125 " sum += ext_array[i];" |
| 8126 "}" |
| 8127 "sum;"); |
| 8128 CHECK_EQ(28, result->Int32Value()); |
| 8129 |
| 8130 // Check pass through of assigned HeapNumbers |
| 8131 result = CompileRun("var sum = 0;" |
| 8132 "for (var i = 0; i < 16; i+=2) {" |
| 8133 " sum += ext_array[i] = ext_array[i] = (-i * 0.5);" |
| 8134 "}" |
| 8135 "sum;"); |
| 8136 CHECK_EQ(-28, result->Int32Value()); |
| 8137 |
| 8138 // Check assigned HeapNumbers |
| 8139 result = CompileRun("for (var i = 0; i < 16; i+=2) {" |
| 8140 " ext_array[i] = (i * 0.5);" |
| 8141 "}" |
| 8142 "var sum = 0;" |
| 8143 "for (var i = 0; i < 16; i+=2) {" |
| 8144 " sum += ext_array[i];" |
| 8145 "}" |
| 8146 "sum;"); |
| 8147 CHECK_EQ(28, result->Int32Value()); |
| 8148 |
| 8149 // Check assigned HeapNumbers in reverse order |
| 8150 result = CompileRun("for (var i = 14; i >= 0; i-=2) {" |
| 8151 " ext_array[i] = (i * 0.5);" |
| 8152 "}" |
| 8153 "var sum = 0;" |
| 8154 "for (var i = 0; i < 16; i+=2) {" |
| 8155 " sum += ext_array[i];" |
| 8156 "}" |
| 8157 "sum;"); |
| 8158 CHECK_EQ(28, result->Int32Value()); |
| 8159 |
| 8160 i::ScopedVector<char> test_buf(1024); |
| 8161 |
| 8162 // Check legal boundary conditions. |
| 8163 // The repeated loads and stores ensure the ICs are exercised. |
| 8164 const char* boundary_program = |
| 8165 "var res = 0;" |
| 8166 "for (var i = 0; i < 16; i++) {" |
| 8167 " ext_array[i] = %lld;" |
| 8168 " if (i > 8) {" |
| 8169 " res = ext_array[i];" |
| 8170 " }" |
| 8171 "}" |
| 8172 "res;"; |
| 8173 i::OS::SNPrintF(test_buf, |
| 8174 boundary_program, |
| 8175 low); |
| 8176 result = CompileRun(test_buf.start()); |
| 8177 CHECK_EQ(low, result->IntegerValue()); |
| 8178 |
| 8179 i::OS::SNPrintF(test_buf, |
| 8180 boundary_program, |
| 8181 high); |
| 8182 result = CompileRun(test_buf.start()); |
| 8183 CHECK_EQ(high, result->IntegerValue()); |
| 8184 |
| 8185 // Check misprediction of type in IC. |
| 8186 result = CompileRun("var tmp_array = ext_array;" |
| 8187 "var sum = 0;" |
| 8188 "for (var i = 0; i < 8; i++) {" |
| 8189 " tmp_array[i] = i;" |
| 8190 " sum += tmp_array[i];" |
| 8191 " if (i == 4) {" |
| 8192 " tmp_array = {};" |
| 8193 " }" |
| 8194 "}" |
| 8195 "sum;"); |
| 8196 i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. |
| 8197 CHECK_EQ(28, result->Int32Value()); |
| 8198 |
| 8199 // Check out-of-range loads. |
| 8200 result = CompileRun("var caught_exception = false;" |
| 8201 "try {" |
| 8202 " ext_array[-1];" |
| 8203 "} catch (e) {" |
| 8204 " caught_exception = true;" |
| 8205 "}" |
| 8206 "caught_exception;"); |
| 8207 CHECK_EQ(true, result->BooleanValue()); |
| 8208 |
| 8209 i::OS::SNPrintF(test_buf, |
| 8210 "var caught_exception = false;" |
| 8211 "try {" |
| 8212 " ext_array[%d];" |
| 8213 "} catch (e) {" |
| 8214 " caught_exception = true;" |
| 8215 "}" |
| 8216 "caught_exception;", |
| 8217 kElementCount); |
| 8218 result = CompileRun(test_buf.start()); |
| 8219 CHECK_EQ(true, result->BooleanValue()); |
| 8220 |
| 8221 // Check out-of-range stores. |
| 8222 result = CompileRun("var caught_exception = false;" |
| 8223 "try {" |
| 8224 " ext_array[-1] = 1;" |
| 8225 "} catch (e) {" |
| 8226 " caught_exception = true;" |
| 8227 "}" |
| 8228 "caught_exception;"); |
| 8229 CHECK_EQ(true, result->BooleanValue()); |
| 8230 |
| 8231 i::OS::SNPrintF(test_buf, |
| 8232 "var caught_exception = false;" |
| 8233 "try {" |
| 8234 " ext_array[%d] = 1;" |
| 8235 "} catch (e) {" |
| 8236 " caught_exception = true;" |
| 8237 "}" |
| 8238 "caught_exception;", |
| 8239 kElementCount); |
| 8240 result = CompileRun(test_buf.start()); |
| 8241 CHECK_EQ(true, result->BooleanValue()); |
| 8242 |
| 8243 // TODO(kbr): check what happens during IC misses on the type of the object. |
| 8244 // Re-assign array object halfway through a loop. |
| 8245 |
| 8246 // Check other boundary conditions, values and operations. |
| 8247 result = CompileRun("for (var i = 0; i < 8; i++) {" |
| 8248 " ext_array[7] = undefined;" |
| 8249 "}" |
| 8250 "ext_array[7];"); |
| 8251 CHECK_EQ(0, result->Int32Value()); |
| 8252 CHECK_EQ(0, static_cast<int>(jsobj->GetElement(7)->Number())); |
| 8253 |
| 8254 result = CompileRun("for (var i = 0; i < 8; i++) {" |
| 8255 " ext_array[6] = '2.3';" |
| 8256 "}" |
| 8257 "ext_array[6];"); |
| 8258 CHECK_EQ(2, result->Int32Value()); |
| 8259 CHECK_EQ(2, static_cast<int>(jsobj->GetElement(6)->Number())); |
| 8260 |
| 8261 // Result for storing NaNs and +/-Infinity isn't defined for these |
| 8262 // types; they do not have the clamping behavior CanvasPixelArray |
| 8263 // specifies. |
| 8264 |
| 8265 result = CompileRun("ext_array[3] = 33;" |
| 8266 "delete ext_array[3];" |
| 8267 "ext_array[3];"); |
| 8268 CHECK_EQ(33, result->Int32Value()); |
| 8269 |
| 8270 result = CompileRun("ext_array[0] = 10; ext_array[1] = 11;" |
| 8271 "ext_array[2] = 12; ext_array[3] = 13;" |
| 8272 "ext_array.__defineGetter__('2'," |
| 8273 "function() { return 120; });" |
| 8274 "ext_array[2];"); |
| 8275 CHECK_EQ(12, result->Int32Value()); |
| 8276 |
| 8277 result = CompileRun("var js_array = new Array(40);" |
| 8278 "js_array[0] = 77;" |
| 8279 "js_array;"); |
| 8280 CHECK_EQ(77, v8::Object::Cast(*result)->Get(v8_str("0"))->Int32Value()); |
| 8281 |
| 8282 result = CompileRun("ext_array[1] = 23;" |
| 8283 "ext_array.__proto__ = [];" |
| 8284 "js_array.__proto__ = ext_array;" |
| 8285 "js_array.concat(ext_array);"); |
| 8286 CHECK_EQ(77, v8::Object::Cast(*result)->Get(v8_str("0"))->Int32Value()); |
| 8287 CHECK_EQ(23, v8::Object::Cast(*result)->Get(v8_str("1"))->Int32Value()); |
| 8288 |
| 8289 result = CompileRun("ext_array[1] = 23;"); |
| 8290 CHECK_EQ(23, result->Int32Value()); |
| 8291 |
| 8292 free(array_data); |
| 8293 } |
| 8294 |
| 8295 |
| 8296 THREADED_TEST(ExternalByteArray) { |
| 8297 ExternalArrayTestHelper<v8::internal::ExternalByteArray, int8_t>( |
| 8298 v8::kExternalByteArray, |
| 8299 -128, |
| 8300 127); |
| 8301 } |
| 8302 |
| 8303 |
| 8304 THREADED_TEST(ExternalUnsignedByteArray) { |
| 8305 ExternalArrayTestHelper<v8::internal::ExternalUnsignedByteArray, uint8_t>( |
| 8306 v8::kExternalUnsignedByteArray, |
| 8307 0, |
| 8308 255); |
| 8309 } |
| 8310 |
| 8311 |
| 8312 THREADED_TEST(ExternalShortArray) { |
| 8313 ExternalArrayTestHelper<v8::internal::ExternalShortArray, int16_t>( |
| 8314 v8::kExternalShortArray, |
| 8315 -32768, |
| 8316 32767); |
| 8317 } |
| 8318 |
| 8319 |
| 8320 THREADED_TEST(ExternalUnsignedShortArray) { |
| 8321 ExternalArrayTestHelper<v8::internal::ExternalUnsignedShortArray, uint16_t>( |
| 8322 v8::kExternalUnsignedShortArray, |
| 8323 0, |
| 8324 65535); |
| 8325 } |
| 8326 |
| 8327 |
| 8328 THREADED_TEST(ExternalIntArray) { |
| 8329 ExternalArrayTestHelper<v8::internal::ExternalIntArray, int32_t>( |
| 8330 v8::kExternalIntArray, |
| 8331 INT_MIN, // -2147483648 |
| 8332 INT_MAX); // 2147483647 |
| 8333 } |
| 8334 |
| 8335 |
| 8336 THREADED_TEST(ExternalUnsignedIntArray) { |
| 8337 ExternalArrayTestHelper<v8::internal::ExternalUnsignedIntArray, uint32_t>( |
| 8338 v8::kExternalUnsignedIntArray, |
| 8339 0, |
| 8340 UINT_MAX); // 4294967295 |
| 8341 } |
| 8342 |
| 8343 |
| 8344 THREADED_TEST(ExternalFloatArray) { |
| 8345 ExternalArrayTestHelper<v8::internal::ExternalFloatArray, float>( |
| 8346 v8::kExternalFloatArray, |
| 8347 -500, |
| 8348 500); |
| 8349 } |
| 8350 |
| 8351 |
| 8352 THREADED_TEST(ExternalArrays) { |
| 8353 TestExternalByteArray(); |
| 8354 TestExternalUnsignedByteArray(); |
| 8355 TestExternalShortArray(); |
| 8356 TestExternalUnsignedShortArray(); |
| 8357 TestExternalIntArray(); |
| 8358 TestExternalUnsignedIntArray(); |
| 8359 TestExternalFloatArray(); |
| 8360 } |
| 8361 |
| 8362 |
8042 THREADED_TEST(ScriptContextDependence) { | 8363 THREADED_TEST(ScriptContextDependence) { |
8043 v8::HandleScope scope; | 8364 v8::HandleScope scope; |
8044 LocalContext c1; | 8365 LocalContext c1; |
8045 const char *source = "foo"; | 8366 const char *source = "foo"; |
8046 v8::Handle<v8::Script> dep = v8::Script::Compile(v8::String::New(source)); | 8367 v8::Handle<v8::Script> dep = v8::Script::Compile(v8::String::New(source)); |
8047 v8::Handle<v8::Script> indep = v8::Script::New(v8::String::New(source)); | 8368 v8::Handle<v8::Script> indep = v8::Script::New(v8::String::New(source)); |
8048 c1->Global()->Set(v8::String::New("foo"), v8::Integer::New(100)); | 8369 c1->Global()->Set(v8::String::New("foo"), v8::Integer::New(100)); |
8049 CHECK_EQ(dep->Run()->Int32Value(), 100); | 8370 CHECK_EQ(dep->Run()->Int32Value(), 100); |
8050 CHECK_EQ(indep->Run()->Int32Value(), 100); | 8371 CHECK_EQ(indep->Run()->Int32Value(), 100); |
8051 LocalContext c2; | 8372 LocalContext c2; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8158 THREADED_TEST(GetHeapStatistics) { | 8479 THREADED_TEST(GetHeapStatistics) { |
8159 v8::HandleScope scope; | 8480 v8::HandleScope scope; |
8160 LocalContext c1; | 8481 LocalContext c1; |
8161 v8::HeapStatistics heap_statistics; | 8482 v8::HeapStatistics heap_statistics; |
8162 CHECK_EQ(heap_statistics.total_heap_size(), 0); | 8483 CHECK_EQ(heap_statistics.total_heap_size(), 0); |
8163 CHECK_EQ(heap_statistics.used_heap_size(), 0); | 8484 CHECK_EQ(heap_statistics.used_heap_size(), 0); |
8164 v8::V8::GetHeapStatistics(&heap_statistics); | 8485 v8::V8::GetHeapStatistics(&heap_statistics); |
8165 CHECK_NE(heap_statistics.total_heap_size(), 0); | 8486 CHECK_NE(heap_statistics.total_heap_size(), 0); |
8166 CHECK_NE(heap_statistics.used_heap_size(), 0); | 8487 CHECK_NE(heap_statistics.used_heap_size(), 0); |
8167 } | 8488 } |
OLD | NEW |