IonIC.h (21358B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef jit_IonIC_h 8 #define jit_IonIC_h 9 10 #include "jit/CacheIR.h" 11 #include "jit/ICState.h" 12 #include "jit/shared/Assembler-shared.h" 13 #include "vm/CompletionKind.h" 14 15 namespace js { 16 namespace jit { 17 18 class CacheIRStubInfo; 19 class CacheIRWriter; 20 class IonScript; 21 22 // An optimized stub attached to an IonIC. 23 class IonICStub { 24 // Code to jump to when this stub fails. This is either the next optimized 25 // stub or the OOL fallback path. 26 uint8_t* nextCodeRaw_; 27 28 // The next optimized stub in this chain, or nullptr if this is the last 29 // one. 30 IonICStub* next_; 31 32 // Info about this stub. 33 CacheIRStubInfo* stubInfo_; 34 35 #ifndef JS_64BIT 36 protected: // Silence Clang warning about unused private fields. 37 // Ensure stub data is 8-byte aligned on 32-bit. 38 uintptr_t padding_ = 0; 39 #endif 40 41 public: 42 IonICStub(uint8_t* fallbackCode, CacheIRStubInfo* stubInfo) 43 : nextCodeRaw_(fallbackCode), next_(nullptr), stubInfo_(stubInfo) {} 44 45 uint8_t* nextCodeRaw() const { return nextCodeRaw_; } 46 uint8_t** nextCodeRawPtr() { return &nextCodeRaw_; } 47 CacheIRStubInfo* stubInfo() const { return stubInfo_; } 48 IonICStub* next() const { return next_; } 49 50 uint8_t* stubDataStart(); 51 52 void setNext(IonICStub* next, uint8_t* nextCodeRaw) { 53 MOZ_ASSERT(!next_); 54 MOZ_ASSERT(next && nextCodeRaw); 55 next_ = next; 56 nextCodeRaw_ = nextCodeRaw; 57 } 58 59 // Null out pointers when we unlink stubs, to ensure we never use 60 // discarded stubs. 61 void poison() { 62 nextCodeRaw_ = nullptr; 63 next_ = nullptr; 64 stubInfo_ = nullptr; 65 } 66 }; 67 68 class IonGetPropertyIC; 69 class IonSetPropertyIC; 70 class IonGetPropSuperIC; 71 class IonGetNameIC; 72 class IonBindNameIC; 73 class IonGetIteratorIC; 74 class IonHasOwnIC; 75 class IonCheckPrivateFieldIC; 76 class IonInIC; 77 class IonInstanceOfIC; 78 class IonCompareIC; 79 class IonUnaryArithIC; 80 class IonBinaryArithIC; 81 class IonToPropertyKeyIC; 82 class IonOptimizeSpreadCallIC; 83 class IonCloseIterIC; 84 class IonOptimizeGetIteratorIC; 85 86 class IonIC { 87 // This either points at the OOL path for the fallback path, or the code for 88 // the first stub. 89 uint8_t* codeRaw_; 90 91 // The first optimized stub, or nullptr. 92 IonICStub* firstStub_; 93 94 // Location of this IC. 95 JSScript* script_; 96 jsbytecode* pc_; 97 98 // The offset of the rejoin location in the IonScript's code (stubs jump to 99 // this location). 100 uint32_t rejoinOffset_; 101 102 // The offset of the OOL path in the IonScript's code that calls the IC's 103 // update function. 104 uint32_t fallbackOffset_; 105 106 CacheKind kind_; 107 ICState state_; 108 109 protected: 110 explicit IonIC(CacheKind kind) 111 : codeRaw_(nullptr), 112 firstStub_(nullptr), 113 script_(nullptr), 114 pc_(nullptr), 115 rejoinOffset_(0), 116 fallbackOffset_(0), 117 kind_(kind) {} 118 119 void attachStub(IonICStub* newStub, JitCode* code); 120 121 public: 122 void setScriptedLocation(JSScript* script, jsbytecode* pc) { 123 MOZ_ASSERT(!script_ && !pc_); 124 MOZ_ASSERT(script && pc); 125 script_ = script; 126 pc_ = pc; 127 } 128 129 JSScript* script() const { 130 MOZ_ASSERT(script_); 131 return script_; 132 } 133 jsbytecode* pc() const { 134 MOZ_ASSERT(pc_); 135 return pc_; 136 } 137 138 // Discard all stubs. 139 void discardStubs(Zone* zone, IonScript* ionScript); 140 141 // Discard all stubs and reset the ICState. 142 void reset(Zone* zone, IonScript* ionScript); 143 144 ICState& state() { return state_; } 145 146 CacheKind kind() const { return kind_; } 147 uint8_t** codeRawPtr() { return &codeRaw_; } 148 149 void setFallbackOffset(CodeOffset offset) { 150 fallbackOffset_ = offset.offset(); 151 } 152 void setRejoinOffset(CodeOffset offset) { rejoinOffset_ = offset.offset(); } 153 154 void resetCodeRaw(IonScript* ionScript); 155 156 uint8_t* fallbackAddr(IonScript* ionScript) const; 157 uint8_t* rejoinAddr(IonScript* ionScript) const; 158 159 IonGetPropertyIC* asGetPropertyIC() { 160 MOZ_ASSERT(kind_ == CacheKind::GetProp || kind_ == CacheKind::GetElem); 161 return (IonGetPropertyIC*)this; 162 } 163 IonSetPropertyIC* asSetPropertyIC() { 164 MOZ_ASSERT(kind_ == CacheKind::SetProp || kind_ == CacheKind::SetElem); 165 return (IonSetPropertyIC*)this; 166 } 167 IonGetPropSuperIC* asGetPropSuperIC() { 168 MOZ_ASSERT(kind_ == CacheKind::GetPropSuper || 169 kind_ == CacheKind::GetElemSuper); 170 return (IonGetPropSuperIC*)this; 171 } 172 IonGetNameIC* asGetNameIC() { 173 MOZ_ASSERT(kind_ == CacheKind::GetName); 174 return (IonGetNameIC*)this; 175 } 176 IonBindNameIC* asBindNameIC() { 177 MOZ_ASSERT(kind_ == CacheKind::BindName); 178 return (IonBindNameIC*)this; 179 } 180 IonGetIteratorIC* asGetIteratorIC() { 181 MOZ_ASSERT(kind_ == CacheKind::GetIterator); 182 return (IonGetIteratorIC*)this; 183 } 184 IonOptimizeSpreadCallIC* asOptimizeSpreadCallIC() { 185 MOZ_ASSERT(kind_ == CacheKind::OptimizeSpreadCall); 186 return (IonOptimizeSpreadCallIC*)this; 187 } 188 IonHasOwnIC* asHasOwnIC() { 189 MOZ_ASSERT(kind_ == CacheKind::HasOwn); 190 return (IonHasOwnIC*)this; 191 } 192 IonCheckPrivateFieldIC* asCheckPrivateFieldIC() { 193 MOZ_ASSERT(kind_ == CacheKind::CheckPrivateField); 194 return (IonCheckPrivateFieldIC*)this; 195 } 196 IonInIC* asInIC() { 197 MOZ_ASSERT(kind_ == CacheKind::In); 198 return (IonInIC*)this; 199 } 200 IonInstanceOfIC* asInstanceOfIC() { 201 MOZ_ASSERT(kind_ == CacheKind::InstanceOf); 202 return (IonInstanceOfIC*)this; 203 } 204 IonCompareIC* asCompareIC() { 205 MOZ_ASSERT(kind_ == CacheKind::Compare); 206 return (IonCompareIC*)this; 207 } 208 IonUnaryArithIC* asUnaryArithIC() { 209 MOZ_ASSERT(kind_ == CacheKind::UnaryArith); 210 return (IonUnaryArithIC*)this; 211 } 212 IonBinaryArithIC* asBinaryArithIC() { 213 MOZ_ASSERT(kind_ == CacheKind::BinaryArith); 214 return (IonBinaryArithIC*)this; 215 } 216 IonToPropertyKeyIC* asToPropertyKeyIC() { 217 MOZ_ASSERT(kind_ == CacheKind::ToPropertyKey); 218 return (IonToPropertyKeyIC*)this; 219 } 220 IonCloseIterIC* asCloseIterIC() { 221 MOZ_ASSERT(kind_ == CacheKind::CloseIter); 222 return (IonCloseIterIC*)this; 223 } 224 IonOptimizeGetIteratorIC* asOptimizeGetIteratorIC() { 225 MOZ_ASSERT(kind_ == CacheKind::OptimizeGetIterator); 226 return (IonOptimizeGetIteratorIC*)this; 227 } 228 229 // Returns the Register to use as scratch when entering IC stubs. This 230 // should either be an output register or a temp. 231 Register scratchRegisterForEntryJump(); 232 233 void trace(JSTracer* trc, IonScript* ionScript); 234 235 void attachCacheIRStub(JSContext* cx, const CacheIRWriter& writer, 236 CacheKind kind, IonScript* ionScript, bool* attached); 237 }; 238 239 class IonGetPropertyIC : public IonIC { 240 private: 241 LiveRegisterSet liveRegs_; 242 243 TypedOrValueRegister value_; 244 ConstantOrRegister id_; 245 ValueOperand output_; 246 247 public: 248 IonGetPropertyIC(CacheKind kind, LiveRegisterSet liveRegs, 249 TypedOrValueRegister value, const ConstantOrRegister& id, 250 ValueOperand output) 251 : IonIC(kind), 252 liveRegs_(liveRegs), 253 value_(value), 254 id_(id), 255 output_(output) {} 256 257 TypedOrValueRegister value() const { return value_; } 258 ConstantOrRegister id() const { return id_; } 259 ValueOperand output() const { return output_; } 260 LiveRegisterSet liveRegs() const { return liveRegs_; } 261 262 [[nodiscard]] static bool update(JSContext* cx, HandleScript outerScript, 263 IonGetPropertyIC* ic, HandleValue val, 264 HandleValue idVal, MutableHandleValue res); 265 }; 266 267 class IonGetPropSuperIC : public IonIC { 268 LiveRegisterSet liveRegs_; 269 270 Register object_; 271 TypedOrValueRegister receiver_; 272 ConstantOrRegister id_; 273 ValueOperand output_; 274 275 public: 276 IonGetPropSuperIC(CacheKind kind, LiveRegisterSet liveRegs, Register object, 277 TypedOrValueRegister receiver, const ConstantOrRegister& id, 278 ValueOperand output) 279 : IonIC(kind), 280 liveRegs_(liveRegs), 281 object_(object), 282 receiver_(receiver), 283 id_(id), 284 output_(output) {} 285 286 Register object() const { return object_; } 287 TypedOrValueRegister receiver() const { return receiver_; } 288 ConstantOrRegister id() const { return id_; } 289 ValueOperand output() const { return output_; } 290 LiveRegisterSet liveRegs() const { return liveRegs_; } 291 292 [[nodiscard]] static bool update(JSContext* cx, HandleScript outerScript, 293 IonGetPropSuperIC* ic, HandleObject obj, 294 HandleValue receiver, HandleValue idVal, 295 MutableHandleValue res); 296 }; 297 298 class IonSetPropertyIC : public IonIC { 299 LiveRegisterSet liveRegs_; 300 301 Register object_; 302 Register temp_; 303 ConstantOrRegister id_; 304 ConstantOrRegister rhs_; 305 bool strict_ : 1; 306 307 public: 308 IonSetPropertyIC(CacheKind kind, LiveRegisterSet liveRegs, Register object, 309 Register temp, const ConstantOrRegister& id, 310 const ConstantOrRegister& rhs, bool strict) 311 : IonIC(kind), 312 liveRegs_(liveRegs), 313 object_(object), 314 temp_(temp), 315 id_(id), 316 rhs_(rhs), 317 strict_(strict) {} 318 319 LiveRegisterSet liveRegs() const { return liveRegs_; } 320 Register object() const { return object_; } 321 ConstantOrRegister id() const { return id_; } 322 ConstantOrRegister rhs() const { return rhs_; } 323 324 Register temp() const { return temp_; } 325 326 bool strict() const { return strict_; } 327 328 [[nodiscard]] static bool update(JSContext* cx, HandleScript outerScript, 329 IonSetPropertyIC* ic, HandleObject obj, 330 HandleValue idVal, HandleValue rhs); 331 }; 332 333 class IonGetNameIC : public IonIC { 334 LiveRegisterSet liveRegs_; 335 336 Register environment_; 337 ValueOperand output_; 338 Register temp_; 339 340 public: 341 IonGetNameIC(LiveRegisterSet liveRegs, Register environment, 342 ValueOperand output, Register temp) 343 : IonIC(CacheKind::GetName), 344 liveRegs_(liveRegs), 345 environment_(environment), 346 output_(output), 347 temp_(temp) {} 348 349 Register environment() const { return environment_; } 350 ValueOperand output() const { return output_; } 351 Register temp() const { return temp_; } 352 LiveRegisterSet liveRegs() const { return liveRegs_; } 353 354 [[nodiscard]] static bool update(JSContext* cx, HandleScript outerScript, 355 IonGetNameIC* ic, HandleObject envChain, 356 MutableHandleValue res); 357 }; 358 359 class IonBindNameIC : public IonIC { 360 LiveRegisterSet liveRegs_; 361 362 Register environment_; 363 Register output_; 364 Register temp_; 365 366 public: 367 IonBindNameIC(LiveRegisterSet liveRegs, Register environment, Register output, 368 Register temp) 369 : IonIC(CacheKind::BindName), 370 liveRegs_(liveRegs), 371 environment_(environment), 372 output_(output), 373 temp_(temp) {} 374 375 Register environment() const { return environment_; } 376 Register output() const { return output_; } 377 Register temp() const { return temp_; } 378 LiveRegisterSet liveRegs() const { return liveRegs_; } 379 380 static JSObject* update(JSContext* cx, HandleScript outerScript, 381 IonBindNameIC* ic, HandleObject envChain); 382 }; 383 384 class IonGetIteratorIC : public IonIC { 385 LiveRegisterSet liveRegs_; 386 TypedOrValueRegister value_; 387 Register output_; 388 Register temp1_; 389 Register temp2_; 390 391 public: 392 IonGetIteratorIC(LiveRegisterSet liveRegs, TypedOrValueRegister value, 393 Register output, Register temp1, Register temp2) 394 : IonIC(CacheKind::GetIterator), 395 liveRegs_(liveRegs), 396 value_(value), 397 output_(output), 398 temp1_(temp1), 399 temp2_(temp2) {} 400 401 TypedOrValueRegister value() const { return value_; } 402 Register output() const { return output_; } 403 Register temp1() const { return temp1_; } 404 Register temp2() const { return temp2_; } 405 LiveRegisterSet liveRegs() const { return liveRegs_; } 406 407 static JSObject* update(JSContext* cx, HandleScript outerScript, 408 IonGetIteratorIC* ic, HandleValue value); 409 }; 410 411 class IonOptimizeSpreadCallIC : public IonIC { 412 LiveRegisterSet liveRegs_; 413 ValueOperand value_; 414 ValueOperand output_; 415 Register temp_; 416 417 public: 418 IonOptimizeSpreadCallIC(LiveRegisterSet liveRegs, ValueOperand value, 419 ValueOperand output, Register temp) 420 : IonIC(CacheKind::OptimizeSpreadCall), 421 liveRegs_(liveRegs), 422 value_(value), 423 output_(output), 424 temp_(temp) {} 425 426 ValueOperand value() const { return value_; } 427 ValueOperand output() const { return output_; } 428 Register temp() const { return temp_; } 429 LiveRegisterSet liveRegs() const { return liveRegs_; } 430 431 static bool update(JSContext* cx, HandleScript outerScript, 432 IonOptimizeSpreadCallIC* ic, HandleValue value, 433 MutableHandleValue result); 434 }; 435 436 class IonHasOwnIC : public IonIC { 437 LiveRegisterSet liveRegs_; 438 439 TypedOrValueRegister value_; 440 TypedOrValueRegister id_; 441 Register output_; 442 443 public: 444 IonHasOwnIC(LiveRegisterSet liveRegs, TypedOrValueRegister value, 445 TypedOrValueRegister id, Register output) 446 : IonIC(CacheKind::HasOwn), 447 liveRegs_(liveRegs), 448 value_(value), 449 id_(id), 450 output_(output) {} 451 452 TypedOrValueRegister value() const { return value_; } 453 TypedOrValueRegister id() const { return id_; } 454 Register output() const { return output_; } 455 LiveRegisterSet liveRegs() const { return liveRegs_; } 456 457 [[nodiscard]] static bool update(JSContext* cx, HandleScript outerScript, 458 IonHasOwnIC* ic, HandleValue val, 459 HandleValue idVal, int32_t* res); 460 }; 461 462 class IonCheckPrivateFieldIC : public IonIC { 463 LiveRegisterSet liveRegs_; 464 465 TypedOrValueRegister value_; 466 TypedOrValueRegister id_; 467 Register output_; 468 469 public: 470 IonCheckPrivateFieldIC(LiveRegisterSet liveRegs, TypedOrValueRegister value, 471 TypedOrValueRegister id, Register output) 472 : IonIC(CacheKind::CheckPrivateField), 473 liveRegs_(liveRegs), 474 value_(value), 475 id_(id), 476 output_(output) {} 477 478 TypedOrValueRegister value() const { return value_; } 479 TypedOrValueRegister id() const { return id_; } 480 Register output() const { return output_; } 481 LiveRegisterSet liveRegs() const { return liveRegs_; } 482 483 [[nodiscard]] static bool update(JSContext* cx, HandleScript outerScript, 484 IonCheckPrivateFieldIC* ic, HandleValue val, 485 HandleValue idVal, bool* res); 486 }; 487 488 class IonInIC : public IonIC { 489 LiveRegisterSet liveRegs_; 490 491 ConstantOrRegister key_; 492 Register object_; 493 Register output_; 494 Register temp_; 495 496 public: 497 IonInIC(LiveRegisterSet liveRegs, const ConstantOrRegister& key, 498 Register object, Register output, Register temp) 499 : IonIC(CacheKind::In), 500 liveRegs_(liveRegs), 501 key_(key), 502 object_(object), 503 output_(output), 504 temp_(temp) {} 505 506 ConstantOrRegister key() const { return key_; } 507 Register object() const { return object_; } 508 Register output() const { return output_; } 509 Register temp() const { return temp_; } 510 LiveRegisterSet liveRegs() const { return liveRegs_; } 511 512 [[nodiscard]] static bool update(JSContext* cx, HandleScript outerScript, 513 IonInIC* ic, HandleValue key, 514 HandleObject obj, bool* res); 515 }; 516 517 class IonInstanceOfIC : public IonIC { 518 LiveRegisterSet liveRegs_; 519 520 TypedOrValueRegister lhs_; 521 Register rhs_; 522 Register output_; 523 524 public: 525 IonInstanceOfIC(LiveRegisterSet liveRegs, TypedOrValueRegister lhs, 526 Register rhs, Register output) 527 : IonIC(CacheKind::InstanceOf), 528 liveRegs_(liveRegs), 529 lhs_(lhs), 530 rhs_(rhs), 531 output_(output) {} 532 533 LiveRegisterSet liveRegs() const { return liveRegs_; } 534 TypedOrValueRegister lhs() const { return lhs_; } 535 Register rhs() const { return rhs_; } 536 Register output() const { return output_; } 537 538 // This signature mimics that of TryAttachInstanceOfStub in baseline 539 [[nodiscard]] static bool update(JSContext* cx, HandleScript outerScript, 540 IonInstanceOfIC* ic, HandleValue lhs, 541 HandleObject rhs, bool* attached); 542 }; 543 544 class IonCompareIC : public IonIC { 545 LiveRegisterSet liveRegs_; 546 547 TypedOrValueRegister lhs_; 548 TypedOrValueRegister rhs_; 549 Register output_; 550 551 public: 552 IonCompareIC(LiveRegisterSet liveRegs, TypedOrValueRegister lhs, 553 TypedOrValueRegister rhs, Register output) 554 : IonIC(CacheKind::Compare), 555 liveRegs_(liveRegs), 556 lhs_(lhs), 557 rhs_(rhs), 558 output_(output) {} 559 560 LiveRegisterSet liveRegs() const { return liveRegs_; } 561 TypedOrValueRegister lhs() const { return lhs_; } 562 TypedOrValueRegister rhs() const { return rhs_; } 563 Register output() const { return output_; } 564 565 [[nodiscard]] static bool update(JSContext* cx, HandleScript outerScript, 566 IonCompareIC* stub, HandleValue lhs, 567 HandleValue rhs, bool* res); 568 }; 569 570 class IonUnaryArithIC : public IonIC { 571 LiveRegisterSet liveRegs_; 572 573 TypedOrValueRegister input_; 574 ValueOperand output_; 575 576 public: 577 IonUnaryArithIC(LiveRegisterSet liveRegs, TypedOrValueRegister input, 578 ValueOperand output) 579 : IonIC(CacheKind::UnaryArith), 580 liveRegs_(liveRegs), 581 input_(input), 582 output_(output) {} 583 584 LiveRegisterSet liveRegs() const { return liveRegs_; } 585 TypedOrValueRegister input() const { return input_; } 586 ValueOperand output() const { return output_; } 587 588 [[nodiscard]] static bool update(JSContext* cx, HandleScript outerScript, 589 IonUnaryArithIC* stub, HandleValue val, 590 MutableHandleValue res); 591 }; 592 593 class IonToPropertyKeyIC : public IonIC { 594 LiveRegisterSet liveRegs_; 595 ValueOperand input_; 596 ValueOperand output_; 597 598 public: 599 IonToPropertyKeyIC(LiveRegisterSet liveRegs, ValueOperand input, 600 ValueOperand output) 601 : IonIC(CacheKind::ToPropertyKey), 602 liveRegs_(liveRegs), 603 input_(input), 604 output_(output) {} 605 606 LiveRegisterSet liveRegs() const { return liveRegs_; } 607 ValueOperand input() const { return input_; } 608 ValueOperand output() const { return output_; } 609 610 [[nodiscard]] static bool update(JSContext* cx, HandleScript outerScript, 611 IonToPropertyKeyIC* ic, HandleValue val, 612 MutableHandleValue res); 613 }; 614 615 class IonBinaryArithIC : public IonIC { 616 LiveRegisterSet liveRegs_; 617 618 TypedOrValueRegister lhs_; 619 TypedOrValueRegister rhs_; 620 ValueOperand output_; 621 622 public: 623 IonBinaryArithIC(LiveRegisterSet liveRegs, TypedOrValueRegister lhs, 624 TypedOrValueRegister rhs, ValueOperand output) 625 : IonIC(CacheKind::BinaryArith), 626 liveRegs_(liveRegs), 627 lhs_(lhs), 628 rhs_(rhs), 629 output_(output) {} 630 631 LiveRegisterSet liveRegs() const { return liveRegs_; } 632 TypedOrValueRegister lhs() const { return lhs_; } 633 TypedOrValueRegister rhs() const { return rhs_; } 634 ValueOperand output() const { return output_; } 635 636 [[nodiscard]] static bool update(JSContext* cx, HandleScript outerScript, 637 IonBinaryArithIC* stub, HandleValue lhs, 638 HandleValue rhs, MutableHandleValue res); 639 }; 640 641 class IonCloseIterIC : public IonIC { 642 LiveRegisterSet liveRegs_; 643 644 Register iter_; 645 Register temp_; 646 CompletionKind completionKind_; 647 648 public: 649 IonCloseIterIC(LiveRegisterSet liveRegs, Register iter, Register temp, 650 CompletionKind completionKind) 651 : IonIC(CacheKind::CloseIter), 652 liveRegs_(liveRegs), 653 iter_(iter), 654 temp_(temp), 655 completionKind_(completionKind) {} 656 657 LiveRegisterSet liveRegs() const { return liveRegs_; } 658 Register temp() const { return temp_; } 659 Register iter() const { return iter_; } 660 CompletionKind completionKind() const { return completionKind_; } 661 662 [[nodiscard]] static bool update(JSContext* cx, HandleScript outerScript, 663 IonCloseIterIC* ic, HandleObject iter); 664 }; 665 666 class IonOptimizeGetIteratorIC : public IonIC { 667 LiveRegisterSet liveRegs_; 668 ValueOperand value_; 669 Register output_; 670 Register temp_; 671 672 public: 673 IonOptimizeGetIteratorIC(LiveRegisterSet liveRegs, ValueOperand value, 674 Register output, Register temp) 675 : IonIC(CacheKind::OptimizeGetIterator), 676 liveRegs_(liveRegs), 677 value_(value), 678 output_(output), 679 temp_(temp) {} 680 681 ValueOperand value() const { return value_; } 682 Register output() const { return output_; } 683 Register temp() const { return temp_; } 684 LiveRegisterSet liveRegs() const { return liveRegs_; } 685 686 static bool update(JSContext* cx, HandleScript outerScript, 687 IonOptimizeGetIteratorIC* ic, HandleValue value, 688 bool* result); 689 }; 690 691 } // namespace jit 692 } // namespace js 693 694 #endif /* jit_IonIC_h */