| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 #include "test/cctest/cctest.h" | 6 #include "test/cctest/cctest.h" |
| 7 | 7 |
| 8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
| 10 #include "src/execution.h" | 10 #include "src/execution.h" |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 Isolate* isolate = CcTest::i_isolate(); | 201 Isolate* isolate = CcTest::i_isolate(); |
| 202 Heap* heap = isolate->heap(); | 202 Heap* heap = isolate->heap(); |
| 203 | 203 |
| 204 // Make sure function f has a call that uses a type feedback slot. | 204 // Make sure function f has a call that uses a type feedback slot. |
| 205 CompileRun( | 205 CompileRun( |
| 206 "function foo() { return 17; }" | 206 "function foo() { return 17; }" |
| 207 "function f(a) { a(); } f(foo);"); | 207 "function f(a) { a(); } f(foo);"); |
| 208 Handle<JSFunction> f = GetFunction("f"); | 208 Handle<JSFunction> f = GetFunction("f"); |
| 209 // There should be one IC. | 209 // There should be one IC. |
| 210 Handle<TypeFeedbackVector> feedback_vector = | 210 Handle<TypeFeedbackVector> feedback_vector = |
| 211 Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate); | 211 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); |
| 212 FeedbackVectorSlot slot(0); | 212 FeedbackVectorSlot slot(0); |
| 213 CallICNexus nexus(feedback_vector, slot); | 213 CallICNexus nexus(feedback_vector, slot); |
| 214 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 214 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
| 215 // CallIC doesn't return map feedback. | 215 // CallIC doesn't return map feedback. |
| 216 CHECK(!nexus.FindFirstMap()); | 216 CHECK(!nexus.FindFirstMap()); |
| 217 | 217 |
| 218 CompileRun("f(function() { return 16; })"); | 218 CompileRun("f(function() { return 16; })"); |
| 219 CHECK_EQ(GENERIC, nexus.StateFromFeedback()); | 219 CHECK_EQ(GENERIC, nexus.StateFromFeedback()); |
| 220 | 220 |
| 221 // After a collection, state should remain GENERIC. | 221 // After a collection, state should remain GENERIC. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 242 Isolate* isolate = CcTest::i_isolate(); | 242 Isolate* isolate = CcTest::i_isolate(); |
| 243 Heap* heap = isolate->heap(); | 243 Heap* heap = isolate->heap(); |
| 244 | 244 |
| 245 // Make sure function f has a call that uses a type feedback slot. | 245 // Make sure function f has a call that uses a type feedback slot. |
| 246 CompileRun( | 246 CompileRun( |
| 247 "var o = { foo: 3 };" | 247 "var o = { foo: 3 };" |
| 248 "function f(a) { return a.foo; } f(o);"); | 248 "function f(a) { return a.foo; } f(o);"); |
| 249 Handle<JSFunction> f = GetFunction("f"); | 249 Handle<JSFunction> f = GetFunction("f"); |
| 250 // There should be one IC. | 250 // There should be one IC. |
| 251 Handle<TypeFeedbackVector> feedback_vector = | 251 Handle<TypeFeedbackVector> feedback_vector = |
| 252 Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate); | 252 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); |
| 253 FeedbackVectorSlot slot(0); | 253 FeedbackVectorSlot slot(0); |
| 254 LoadICNexus nexus(feedback_vector, slot); | 254 LoadICNexus nexus(feedback_vector, slot); |
| 255 CHECK_EQ(PREMONOMORPHIC, nexus.StateFromFeedback()); | 255 CHECK_EQ(PREMONOMORPHIC, nexus.StateFromFeedback()); |
| 256 | 256 |
| 257 CompileRun("f(o)"); | 257 CompileRun("f(o)"); |
| 258 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 258 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
| 259 // Verify that the monomorphic map is the one we expect. | 259 // Verify that the monomorphic map is the one we expect. |
| 260 v8::MaybeLocal<v8::Value> v8_o = | 260 v8::MaybeLocal<v8::Value> v8_o = |
| 261 CcTest::global()->Get(context.local(), v8_str("o")); | 261 CcTest::global()->Get(context.local(), v8_str("o")); |
| 262 Handle<JSObject> o = | 262 Handle<JSObject> o = |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 CompileRun( | 301 CompileRun( |
| 302 "o = 10;" | 302 "o = 10;" |
| 303 "function f() {" | 303 "function f() {" |
| 304 " var x = o + 10;" | 304 " var x = o + 10;" |
| 305 " return o + x + o;" | 305 " return o + x + o;" |
| 306 "}" | 306 "}" |
| 307 "f();"); | 307 "f();"); |
| 308 Handle<JSFunction> f = GetFunction("f"); | 308 Handle<JSFunction> f = GetFunction("f"); |
| 309 // There should be one IC slot. | 309 // There should be one IC slot. |
| 310 Handle<TypeFeedbackVector> feedback_vector = | 310 Handle<TypeFeedbackVector> feedback_vector = |
| 311 Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate); | 311 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); |
| 312 FeedbackVectorHelper helper(feedback_vector); | 312 FeedbackVectorHelper helper(feedback_vector); |
| 313 CHECK_EQ(1, helper.slot_count()); | 313 CHECK_EQ(1, helper.slot_count()); |
| 314 FeedbackVectorSlot slot(0); | 314 FeedbackVectorSlot slot(0); |
| 315 LoadICNexus nexus(feedback_vector, slot); | 315 LoadICNexus nexus(feedback_vector, slot); |
| 316 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 316 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
| 317 } | 317 } |
| 318 | 318 |
| 319 | 319 |
| 320 TEST(VectorLoadICOnSmi) { | 320 TEST(VectorLoadICOnSmi) { |
| 321 if (i::FLAG_always_opt) return; | 321 if (i::FLAG_always_opt) return; |
| 322 CcTest::InitializeVM(); | 322 CcTest::InitializeVM(); |
| 323 LocalContext context; | 323 LocalContext context; |
| 324 v8::HandleScope scope(context->GetIsolate()); | 324 v8::HandleScope scope(context->GetIsolate()); |
| 325 Isolate* isolate = CcTest::i_isolate(); | 325 Isolate* isolate = CcTest::i_isolate(); |
| 326 Heap* heap = isolate->heap(); | 326 Heap* heap = isolate->heap(); |
| 327 | 327 |
| 328 // Make sure function f has a call that uses a type feedback slot. | 328 // Make sure function f has a call that uses a type feedback slot. |
| 329 CompileRun( | 329 CompileRun( |
| 330 "var o = { foo: 3 };" | 330 "var o = { foo: 3 };" |
| 331 "function f(a) { return a.foo; } f(o);"); | 331 "function f(a) { return a.foo; } f(o);"); |
| 332 Handle<JSFunction> f = GetFunction("f"); | 332 Handle<JSFunction> f = GetFunction("f"); |
| 333 // There should be one IC. | 333 // There should be one IC. |
| 334 Handle<TypeFeedbackVector> feedback_vector = | 334 Handle<TypeFeedbackVector> feedback_vector = |
| 335 Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate); | 335 Handle<TypeFeedbackVector>(f->feedback_vector(), isolate); |
| 336 FeedbackVectorSlot slot(0); | 336 FeedbackVectorSlot slot(0); |
| 337 LoadICNexus nexus(feedback_vector, slot); | 337 LoadICNexus nexus(feedback_vector, slot); |
| 338 CHECK_EQ(PREMONOMORPHIC, nexus.StateFromFeedback()); | 338 CHECK_EQ(PREMONOMORPHIC, nexus.StateFromFeedback()); |
| 339 | 339 |
| 340 CompileRun("f(34)"); | 340 CompileRun("f(34)"); |
| 341 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 341 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
| 342 // Verify that the monomorphic map is the one we expect. | 342 // Verify that the monomorphic map is the one we expect. |
| 343 Map* number_map = heap->heap_number_map(); | 343 Map* number_map = heap->heap_number_map(); |
| 344 CHECK_EQ(number_map, nexus.FindFirstMap()); | 344 CHECK_EQ(number_map, nexus.FindFirstMap()); |
| 345 | 345 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 " y = a;" | 390 " y = a;" |
| 391 " return y;" | 391 " return y;" |
| 392 "}" | 392 "}" |
| 393 "a = 3;" | 393 "a = 3;" |
| 394 "testvar({});"); | 394 "testvar({});"); |
| 395 | 395 |
| 396 Handle<JSFunction> f = GetFunction("testvar"); | 396 Handle<JSFunction> f = GetFunction("testvar"); |
| 397 | 397 |
| 398 // There should be two LOAD_ICs, one for a and one for y at the end. | 398 // There should be two LOAD_ICs, one for a and one for y at the end. |
| 399 Handle<TypeFeedbackVector> feedback_vector = | 399 Handle<TypeFeedbackVector> feedback_vector = |
| 400 handle(f->shared()->feedback_vector(), isolate); | 400 handle(f->feedback_vector(), isolate); |
| 401 FeedbackVectorHelper helper(feedback_vector); | 401 FeedbackVectorHelper helper(feedback_vector); |
| 402 CHECK_EQ(4, helper.slot_count()); | 402 CHECK_EQ(4, helper.slot_count()); |
| 403 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::STORE_IC); | 403 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::STORE_IC); |
| 404 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); | 404 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); |
| 405 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); | 405 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); |
| 406 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::LOAD_IC); | 406 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::LOAD_IC); |
| 407 } | 407 } |
| 408 | 408 |
| 409 { | 409 { |
| 410 CompileRun( | 410 CompileRun( |
| 411 "function testprop(x) {" | 411 "function testprop(x) {" |
| 412 " x.blue = a;" | 412 " x.blue = a;" |
| 413 "}" | 413 "}" |
| 414 "testprop({ blue: 3 });"); | 414 "testprop({ blue: 3 });"); |
| 415 | 415 |
| 416 Handle<JSFunction> f = GetFunction("testprop"); | 416 Handle<JSFunction> f = GetFunction("testprop"); |
| 417 | 417 |
| 418 // There should be one LOAD_IC, for the load of a. | 418 // There should be one LOAD_IC, for the load of a. |
| 419 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); | 419 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
| 420 FeedbackVectorHelper helper(feedback_vector); | 420 FeedbackVectorHelper helper(feedback_vector); |
| 421 CHECK_EQ(2, helper.slot_count()); | 421 CHECK_EQ(2, helper.slot_count()); |
| 422 } | 422 } |
| 423 | 423 |
| 424 { | 424 { |
| 425 CompileRun( | 425 CompileRun( |
| 426 "function testpropfunc(x) {" | 426 "function testpropfunc(x) {" |
| 427 " x().blue = a;" | 427 " x().blue = a;" |
| 428 " return x().blue;" | 428 " return x().blue;" |
| 429 "}" | 429 "}" |
| 430 "function makeresult() { return { blue: 3 }; }" | 430 "function makeresult() { return { blue: 3 }; }" |
| 431 "testpropfunc(makeresult);"); | 431 "testpropfunc(makeresult);"); |
| 432 | 432 |
| 433 Handle<JSFunction> f = GetFunction("testpropfunc"); | 433 Handle<JSFunction> f = GetFunction("testpropfunc"); |
| 434 | 434 |
| 435 // There should be 2 LOAD_ICs and 2 CALL_ICs. | 435 // There should be 2 LOAD_ICs and 2 CALL_ICs. |
| 436 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); | 436 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
| 437 FeedbackVectorHelper helper(feedback_vector); | 437 FeedbackVectorHelper helper(feedback_vector); |
| 438 CHECK_EQ(5, helper.slot_count()); | 438 CHECK_EQ(5, helper.slot_count()); |
| 439 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::CALL_IC); | 439 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::CALL_IC); |
| 440 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); | 440 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); |
| 441 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); | 441 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); |
| 442 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::CALL_IC); | 442 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::CALL_IC); |
| 443 CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); | 443 CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); |
| 444 } | 444 } |
| 445 | 445 |
| 446 { | 446 { |
| 447 CompileRun( | 447 CompileRun( |
| 448 "function testkeyedprop(x) {" | 448 "function testkeyedprop(x) {" |
| 449 " x[0] = a;" | 449 " x[0] = a;" |
| 450 " return x[0];" | 450 " return x[0];" |
| 451 "}" | 451 "}" |
| 452 "testkeyedprop([0, 1, 2]);"); | 452 "testkeyedprop([0, 1, 2]);"); |
| 453 | 453 |
| 454 Handle<JSFunction> f = GetFunction("testkeyedprop"); | 454 Handle<JSFunction> f = GetFunction("testkeyedprop"); |
| 455 | 455 |
| 456 // There should be 1 LOAD_ICs for the load of a, and one KEYED_LOAD_IC for | 456 // There should be 1 LOAD_ICs for the load of a, and one KEYED_LOAD_IC for |
| 457 // the load of x[0] in the return statement. | 457 // the load of x[0] in the return statement. |
| 458 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); | 458 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
| 459 FeedbackVectorHelper helper(feedback_vector); | 459 FeedbackVectorHelper helper(feedback_vector); |
| 460 CHECK_EQ(3, helper.slot_count()); | 460 CHECK_EQ(3, helper.slot_count()); |
| 461 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); | 461 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); |
| 462 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::KEYED_STORE_IC); | 462 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::KEYED_STORE_IC); |
| 463 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::KEYED_LOAD_IC); | 463 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::KEYED_LOAD_IC); |
| 464 } | 464 } |
| 465 | 465 |
| 466 { | 466 { |
| 467 CompileRun( | 467 CompileRun( |
| 468 "function testcompound(x) {" | 468 "function testcompound(x) {" |
| 469 " x.old = x.young = x.in_between = a;" | 469 " x.old = x.young = x.in_between = a;" |
| 470 " return x.old + x.young;" | 470 " return x.old + x.young;" |
| 471 "}" | 471 "}" |
| 472 "testcompound({ old: 3, young: 3, in_between: 3 });"); | 472 "testcompound({ old: 3, young: 3, in_between: 3 });"); |
| 473 | 473 |
| 474 Handle<JSFunction> f = GetFunction("testcompound"); | 474 Handle<JSFunction> f = GetFunction("testcompound"); |
| 475 | 475 |
| 476 // There should be 3 LOAD_ICs, for load of a and load of x.old and x.young. | 476 // There should be 3 LOAD_ICs, for load of a and load of x.old and x.young. |
| 477 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); | 477 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
| 478 FeedbackVectorHelper helper(feedback_vector); | 478 FeedbackVectorHelper helper(feedback_vector); |
| 479 CHECK_EQ(6, helper.slot_count()); | 479 CHECK_EQ(6, helper.slot_count()); |
| 480 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); | 480 CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); |
| 481 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::STORE_IC); | 481 CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::STORE_IC); |
| 482 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); | 482 CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); |
| 483 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::STORE_IC); | 483 CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::STORE_IC); |
| 484 CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); | 484 CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); |
| 485 CHECK_SLOT_KIND(helper, 5, FeedbackVectorSlotKind::LOAD_IC); | 485 CHECK_SLOT_KIND(helper, 5, FeedbackVectorSlotKind::LOAD_IC); |
| 486 } | 486 } |
| 487 } | 487 } |
| 488 | 488 |
| 489 | 489 |
| 490 TEST(VectorStoreICBasic) { | 490 TEST(VectorStoreICBasic) { |
| 491 if (i::FLAG_always_opt) return; | 491 if (i::FLAG_always_opt) return; |
| 492 | 492 |
| 493 CcTest::InitializeVM(); | 493 CcTest::InitializeVM(); |
| 494 LocalContext context; | 494 LocalContext context; |
| 495 v8::HandleScope scope(context->GetIsolate()); | 495 v8::HandleScope scope(context->GetIsolate()); |
| 496 | 496 |
| 497 CompileRun( | 497 CompileRun( |
| 498 "function f(a) {" | 498 "function f(a) {" |
| 499 " a.foo = 5;" | 499 " a.foo = 5;" |
| 500 "}" | 500 "}" |
| 501 "var a = { foo: 3 };" | 501 "var a = { foo: 3 };" |
| 502 "f(a);" | 502 "f(a);" |
| 503 "f(a);" | 503 "f(a);" |
| 504 "f(a);"); | 504 "f(a);"); |
| 505 Handle<JSFunction> f = GetFunction("f"); | 505 Handle<JSFunction> f = GetFunction("f"); |
| 506 // There should be one IC slot. | 506 // There should be one IC slot. |
| 507 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); | 507 Handle<TypeFeedbackVector> feedback_vector(f->feedback_vector()); |
| 508 FeedbackVectorHelper helper(feedback_vector); | 508 FeedbackVectorHelper helper(feedback_vector); |
| 509 CHECK_EQ(1, helper.slot_count()); | 509 CHECK_EQ(1, helper.slot_count()); |
| 510 FeedbackVectorSlot slot(0); | 510 FeedbackVectorSlot slot(0); |
| 511 StoreICNexus nexus(feedback_vector, slot); | 511 StoreICNexus nexus(feedback_vector, slot); |
| 512 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); | 512 CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback()); |
| 513 } | 513 } |
| 514 | 514 |
| 515 } // namespace | 515 } // namespace |
| OLD | NEW |