| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 Address address_; | 191 Address address_; |
| 192 IC::UtilityId id_; | 192 IC::UtilityId id_; |
| 193 }; | 193 }; |
| 194 | 194 |
| 195 | 195 |
| 196 class CallICBase: public IC { | 196 class CallICBase: public IC { |
| 197 public: | 197 public: |
| 198 class Contextual: public BitField<bool, 0, 1> {}; | 198 class Contextual: public BitField<bool, 0, 1> {}; |
| 199 class StringStubState: public BitField<StringStubFeedback, 1, 1> {}; | 199 class StringStubState: public BitField<StringStubFeedback, 1, 1> {}; |
| 200 | 200 |
| 201 protected: | 201 // Returns a JSFunction or a Failure. |
| 202 CallICBase(Code::Kind kind, Isolate* isolate) | |
| 203 : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {} | |
| 204 | |
| 205 public: | |
| 206 MUST_USE_RESULT MaybeObject* LoadFunction(State state, | 202 MUST_USE_RESULT MaybeObject* LoadFunction(State state, |
| 207 Code::ExtraICState extra_ic_state, | 203 Code::ExtraICState extra_ic_state, |
| 208 Handle<Object> object, | 204 Handle<Object> object, |
| 209 Handle<String> name); | 205 Handle<String> name); |
| 210 | 206 |
| 211 protected: | 207 protected: |
| 212 Code::Kind kind_; | 208 CallICBase(Code::Kind kind, Isolate* isolate) |
| 209 : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {} |
| 213 | 210 |
| 214 bool TryUpdateExtraICState(LookupResult* lookup, | 211 bool TryUpdateExtraICState(LookupResult* lookup, |
| 215 Handle<Object> object, | 212 Handle<Object> object, |
| 216 Code::ExtraICState* extra_ic_state); | 213 Code::ExtraICState* extra_ic_state); |
| 217 | 214 |
| 218 MUST_USE_RESULT MaybeObject* ComputeMonomorphicStub( | 215 // Compute a monomorphic stub if possible, otherwise return a null handle. |
| 219 LookupResult* lookup, | 216 Handle<Code> ComputeMonomorphicStub(LookupResult* lookup, |
| 220 State state, | 217 State state, |
| 221 Code::ExtraICState extra_ic_state, | 218 Code::ExtraICState extra_state, |
| 222 Handle<Object> object, | 219 Handle<Object> object, |
| 223 Handle<String> name); | 220 Handle<String> name); |
| 224 | 221 |
| 225 // Update the inline cache and the global stub cache based on the | 222 // Update the inline cache and the global stub cache based on the lookup |
| 226 // lookup result. | 223 // result. |
| 227 void UpdateCaches(LookupResult* lookup, | 224 void UpdateCaches(LookupResult* lookup, |
| 228 State state, | 225 State state, |
| 229 Code::ExtraICState extra_ic_state, | 226 Code::ExtraICState extra_ic_state, |
| 230 Handle<Object> object, | 227 Handle<Object> object, |
| 231 Handle<String> name); | 228 Handle<String> name); |
| 232 | 229 |
| 233 // Returns a JSFunction if the object can be called as a function, | 230 // Returns a JSFunction if the object can be called as a function, and |
| 234 // and patches the stack to be ready for the call. | 231 // patches the stack to be ready for the call. Otherwise, it returns the |
| 235 // Otherwise, it returns the undefined value. | 232 // undefined value. |
| 236 Object* TryCallAsFunction(Object* object); | 233 Handle<Object> TryCallAsFunction(Handle<Object> object); |
| 237 | 234 |
| 238 void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object); | 235 void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object); |
| 239 | 236 |
| 240 static void Clear(Address address, Code* target); | 237 static void Clear(Address address, Code* target); |
| 241 | 238 |
| 239 // Platform-specific code generation functions used by both call and |
| 240 // keyed call. |
| 241 static void GenerateMiss(MacroAssembler* masm, |
| 242 int argc, |
| 243 IC::UtilityId id, |
| 244 Code::ExtraICState extra_state); |
| 245 |
| 246 static void GenerateNormal(MacroAssembler* masm, int argc); |
| 247 |
| 248 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, |
| 249 int argc, |
| 250 Code::Kind kind, |
| 251 Code::ExtraICState extra_state); |
| 252 |
| 253 Code::Kind kind_; |
| 254 |
| 242 friend class IC; | 255 friend class IC; |
| 243 }; | 256 }; |
| 244 | 257 |
| 245 | 258 |
| 246 class CallIC: public CallICBase { | 259 class CallIC: public CallICBase { |
| 247 public: | 260 public: |
| 248 explicit CallIC(Isolate* isolate) : CallICBase(Code::CALL_IC, isolate) { | 261 explicit CallIC(Isolate* isolate) : CallICBase(Code::CALL_IC, isolate) { |
| 249 ASSERT(target()->is_call_stub()); | 262 ASSERT(target()->is_call_stub()); |
| 250 } | 263 } |
| 251 | 264 |
| 252 // Code generator routines. | 265 // Code generator routines. |
| 253 static void GenerateInitialize(MacroAssembler* masm, | 266 static void GenerateInitialize(MacroAssembler* masm, |
| 254 int argc, | 267 int argc, |
| 255 Code::ExtraICState extra_ic_state) { | 268 Code::ExtraICState extra_state) { |
| 256 GenerateMiss(masm, argc, extra_ic_state); | 269 GenerateMiss(masm, argc, extra_state); |
| 257 } | 270 } |
| 271 |
| 258 static void GenerateMiss(MacroAssembler* masm, | 272 static void GenerateMiss(MacroAssembler* masm, |
| 259 int argc, | 273 int argc, |
| 260 Code::ExtraICState extra_ic_state); | 274 Code::ExtraICState extra_state) { |
| 275 CallICBase::GenerateMiss(masm, argc, IC::kCallIC_Miss, extra_state); |
| 276 } |
| 277 |
| 261 static void GenerateMegamorphic(MacroAssembler* masm, | 278 static void GenerateMegamorphic(MacroAssembler* masm, |
| 262 int argc, | 279 int argc, |
| 263 Code::ExtraICState extra_ic_state); | 280 Code::ExtraICState extra_ic_state); |
| 264 static void GenerateNormal(MacroAssembler* masm, int argc); | 281 |
| 282 static void GenerateNormal(MacroAssembler* masm, int argc) { |
| 283 CallICBase::GenerateNormal(masm, argc); |
| 284 GenerateMiss(masm, argc, Code::kNoExtraICState); |
| 285 } |
| 265 }; | 286 }; |
| 266 | 287 |
| 267 | 288 |
| 268 class KeyedCallIC: public CallICBase { | 289 class KeyedCallIC: public CallICBase { |
| 269 public: | 290 public: |
| 270 explicit KeyedCallIC(Isolate* isolate) | 291 explicit KeyedCallIC(Isolate* isolate) |
| 271 : CallICBase(Code::KEYED_CALL_IC, isolate) { | 292 : CallICBase(Code::KEYED_CALL_IC, isolate) { |
| 272 ASSERT(target()->is_keyed_call_stub()); | 293 ASSERT(target()->is_keyed_call_stub()); |
| 273 } | 294 } |
| 274 | 295 |
| 275 MUST_USE_RESULT MaybeObject* LoadFunction(State state, | 296 MUST_USE_RESULT MaybeObject* LoadFunction(State state, |
| 276 Handle<Object> object, | 297 Handle<Object> object, |
| 277 Handle<Object> key); | 298 Handle<Object> key); |
| 278 | 299 |
| 279 // Code generator routines. | 300 // Code generator routines. |
| 280 static void GenerateInitialize(MacroAssembler* masm, int argc) { | 301 static void GenerateInitialize(MacroAssembler* masm, int argc) { |
| 281 GenerateMiss(masm, argc); | 302 GenerateMiss(masm, argc); |
| 282 } | 303 } |
| 283 static void GenerateMiss(MacroAssembler* masm, int argc); | 304 |
| 305 static void GenerateMiss(MacroAssembler* masm, int argc) { |
| 306 CallICBase::GenerateMiss(masm, argc, IC::kKeyedCallIC_Miss, |
| 307 Code::kNoExtraICState); |
| 308 } |
| 309 |
| 284 static void GenerateMegamorphic(MacroAssembler* masm, int argc); | 310 static void GenerateMegamorphic(MacroAssembler* masm, int argc); |
| 285 static void GenerateNormal(MacroAssembler* masm, int argc); | 311 static void GenerateNormal(MacroAssembler* masm, int argc); |
| 286 static void GenerateNonStrictArguments(MacroAssembler* masm, int argc); | 312 static void GenerateNonStrictArguments(MacroAssembler* masm, int argc); |
| 287 }; | 313 }; |
| 288 | 314 |
| 289 | 315 |
| 290 class LoadIC: public IC { | 316 class LoadIC: public IC { |
| 291 public: | 317 public: |
| 292 explicit LoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { | 318 explicit LoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { |
| 293 ASSERT(target()->is_load_stub()); | 319 ASSERT(target()->is_load_stub()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 314 | 340 |
| 315 private: | 341 private: |
| 316 // Update the inline cache and the global stub cache based on the | 342 // Update the inline cache and the global stub cache based on the |
| 317 // lookup result. | 343 // lookup result. |
| 318 void UpdateCaches(LookupResult* lookup, | 344 void UpdateCaches(LookupResult* lookup, |
| 319 State state, | 345 State state, |
| 320 Handle<Object> object, | 346 Handle<Object> object, |
| 321 Handle<String> name); | 347 Handle<String> name); |
| 322 | 348 |
| 323 // Stub accessors. | 349 // Stub accessors. |
| 324 Code* megamorphic_stub() { | 350 Handle<Code> megamorphic_stub() { |
| 325 return isolate()->builtins()->builtin( | 351 return isolate()->builtins()->LoadIC_Megamorphic(); |
| 326 Builtins::kLoadIC_Megamorphic); | |
| 327 } | 352 } |
| 328 static Code* initialize_stub() { | 353 static Code* initialize_stub() { |
| 329 return Isolate::Current()->builtins()->builtin( | 354 return Isolate::Current()->builtins()->builtin( |
| 330 Builtins::kLoadIC_Initialize); | 355 Builtins::kLoadIC_Initialize); |
| 331 } | 356 } |
| 332 Code* pre_monomorphic_stub() { | 357 Handle<Code> pre_monomorphic_stub() { |
| 333 return isolate()->builtins()->builtin( | 358 return isolate()->builtins()->LoadIC_PreMonomorphic(); |
| 334 Builtins::kLoadIC_PreMonomorphic); | |
| 335 } | 359 } |
| 336 | 360 |
| 337 static void Clear(Address address, Code* target); | 361 static void Clear(Address address, Code* target); |
| 338 | 362 |
| 339 friend class IC; | 363 friend class IC; |
| 340 }; | 364 }; |
| 341 | 365 |
| 342 | 366 |
| 343 class KeyedIC: public IC { | 367 class KeyedIC: public IC { |
| 344 public: | 368 public: |
| 345 enum StubKind { | 369 enum StubKind { |
| 346 LOAD, | 370 LOAD, |
| 347 STORE_NO_TRANSITION, | 371 STORE_NO_TRANSITION, |
| 348 STORE_TRANSITION_SMI_TO_OBJECT, | 372 STORE_TRANSITION_SMI_TO_OBJECT, |
| 349 STORE_TRANSITION_SMI_TO_DOUBLE, | 373 STORE_TRANSITION_SMI_TO_DOUBLE, |
| 350 STORE_TRANSITION_DOUBLE_TO_OBJECT | 374 STORE_TRANSITION_DOUBLE_TO_OBJECT |
| 351 }; | 375 }; |
| 352 explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {} | 376 explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {} |
| 353 virtual ~KeyedIC() {} | 377 virtual ~KeyedIC() {} |
| 354 | 378 |
| 355 virtual MaybeObject* GetElementStubWithoutMapCheck( | 379 virtual Handle<Code> GetElementStubWithoutMapCheck( |
| 356 bool is_js_array, | 380 bool is_js_array, |
| 357 ElementsKind elements_kind) = 0; | 381 ElementsKind elements_kind) = 0; |
| 358 | 382 |
| 359 protected: | 383 protected: |
| 360 virtual Code* string_stub() { | 384 virtual Handle<Code> string_stub() { |
| 361 return NULL; | 385 return Handle<Code>::null(); |
| 362 } | 386 } |
| 363 | 387 |
| 364 virtual Code::Kind kind() const = 0; | 388 virtual Code::Kind kind() const = 0; |
| 365 | 389 |
| 366 MaybeObject* ComputeStub(JSObject* receiver, | 390 Handle<Code> ComputeStub(Handle<JSObject> receiver, |
| 367 StubKind stub_kind, | 391 StubKind stub_kind, |
| 368 StrictModeFlag strict_mode, | 392 StrictModeFlag strict_mode, |
| 369 Code* default_stub); | 393 Handle<Code> default_stub); |
| 370 | 394 |
| 371 virtual MaybeObject* ComputePolymorphicStub(MapList* receiver_maps, | 395 virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps, |
| 372 StrictModeFlag strict_mode) = 0; | 396 StrictModeFlag strict_mode) = 0; |
| 373 | 397 |
| 374 MaybeObject* ComputeMonomorphicStubWithoutMapCheck( | 398 Handle<Code> ComputeMonomorphicStubWithoutMapCheck( |
| 375 Map* receiver_map, | 399 Handle<Map> receiver_map, |
| 376 StrictModeFlag strict_mode); | 400 StrictModeFlag strict_mode); |
| 377 | 401 |
| 378 private: | 402 private: |
| 379 void GetReceiverMapsForStub(Code* stub, MapList* result); | 403 void GetReceiverMapsForStub(Handle<Code> stub, MapHandleList* result); |
| 380 | 404 |
| 381 MaybeObject* ComputeMonomorphicStub(JSObject* receiver, | 405 Handle<Code> ComputeMonomorphicStub(Handle<JSObject> receiver, |
| 382 StubKind stub_kind, | 406 StubKind stub_kind, |
| 383 StrictModeFlag strict_mode, | 407 StrictModeFlag strict_mode, |
| 384 Code* default_stub); | 408 Handle<Code> default_stub); |
| 385 | 409 |
| 386 MaybeObject* ComputeTransitionedMap(JSObject* receiver, StubKind stub_kind); | 410 Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver, |
| 411 StubKind stub_kind); |
| 387 | 412 |
| 388 static bool IsTransitionStubKind(StubKind stub_kind) { | 413 static bool IsTransitionStubKind(StubKind stub_kind) { |
| 389 return stub_kind > STORE_NO_TRANSITION; | 414 return stub_kind > STORE_NO_TRANSITION; |
| 390 } | 415 } |
| 391 }; | 416 }; |
| 392 | 417 |
| 393 | 418 |
| 394 class KeyedLoadIC: public KeyedIC { | 419 class KeyedLoadIC: public KeyedIC { |
| 395 public: | 420 public: |
| 396 explicit KeyedLoadIC(Isolate* isolate) : KeyedIC(isolate) { | 421 explicit KeyedLoadIC(Isolate* isolate) : KeyedIC(isolate) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 416 static void GenerateIndexedInterceptor(MacroAssembler* masm); | 441 static void GenerateIndexedInterceptor(MacroAssembler* masm); |
| 417 static void GenerateNonStrictArguments(MacroAssembler* masm); | 442 static void GenerateNonStrictArguments(MacroAssembler* masm); |
| 418 | 443 |
| 419 // Bit mask to be tested against bit field for the cases when | 444 // Bit mask to be tested against bit field for the cases when |
| 420 // generic stub should go into slow case. | 445 // generic stub should go into slow case. |
| 421 // Access check is necessary explicitly since generic stub does not perform | 446 // Access check is necessary explicitly since generic stub does not perform |
| 422 // map checks. | 447 // map checks. |
| 423 static const int kSlowCaseBitFieldMask = | 448 static const int kSlowCaseBitFieldMask = |
| 424 (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor); | 449 (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor); |
| 425 | 450 |
| 426 virtual MaybeObject* GetElementStubWithoutMapCheck( | 451 virtual Handle<Code> GetElementStubWithoutMapCheck( |
| 427 bool is_js_array, | 452 bool is_js_array, |
| 428 ElementsKind elements_kind); | 453 ElementsKind elements_kind); |
| 429 | 454 |
| 430 protected: | 455 protected: |
| 431 virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } | 456 virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } |
| 432 | 457 |
| 433 virtual MaybeObject* ComputePolymorphicStub( | 458 virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps, |
| 434 MapList* receiver_maps, | 459 StrictModeFlag strict_mode); |
| 435 StrictModeFlag strict_mode); | |
| 436 | 460 |
| 437 virtual Code* string_stub() { | 461 virtual Handle<Code> string_stub() { |
| 438 return isolate()->builtins()->builtin( | 462 return isolate()->builtins()->KeyedLoadIC_String(); |
| 439 Builtins::kKeyedLoadIC_String); | |
| 440 } | 463 } |
| 441 | 464 |
| 442 private: | 465 private: |
| 443 // Update the inline cache. | 466 // Update the inline cache. |
| 444 void UpdateCaches(LookupResult* lookup, | 467 void UpdateCaches(LookupResult* lookup, |
| 445 State state, | 468 State state, |
| 446 Handle<Object> object, | 469 Handle<Object> object, |
| 447 Handle<String> name); | 470 Handle<String> name); |
| 448 | 471 |
| 449 // Stub accessors. | 472 // Stub accessors. |
| 450 static Code* initialize_stub() { | 473 static Code* initialize_stub() { |
| 451 return Isolate::Current()->builtins()->builtin( | 474 return Isolate::Current()->builtins()->builtin( |
| 452 Builtins::kKeyedLoadIC_Initialize); | 475 Builtins::kKeyedLoadIC_Initialize); |
| 453 } | 476 } |
| 454 Code* megamorphic_stub() { | 477 Handle<Code> megamorphic_stub() { |
| 455 return isolate()->builtins()->builtin( | 478 return isolate()->builtins()->KeyedLoadIC_Generic(); |
| 456 Builtins::kKeyedLoadIC_Generic); | |
| 457 } | 479 } |
| 458 Code* generic_stub() { | 480 Handle<Code> generic_stub() { |
| 459 return isolate()->builtins()->builtin( | 481 return isolate()->builtins()->KeyedLoadIC_Generic(); |
| 460 Builtins::kKeyedLoadIC_Generic); | |
| 461 } | 482 } |
| 462 Code* pre_monomorphic_stub() { | 483 Handle<Code> pre_monomorphic_stub() { |
| 463 return isolate()->builtins()->builtin( | 484 return isolate()->builtins()->KeyedLoadIC_PreMonomorphic(); |
| 464 Builtins::kKeyedLoadIC_PreMonomorphic); | |
| 465 } | 485 } |
| 466 Code* indexed_interceptor_stub() { | 486 Handle<Code> indexed_interceptor_stub() { |
| 467 return isolate()->builtins()->builtin( | 487 return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor(); |
| 468 Builtins::kKeyedLoadIC_IndexedInterceptor); | |
| 469 } | 488 } |
| 470 Code* non_strict_arguments_stub() { | 489 Handle<Code> non_strict_arguments_stub() { |
| 471 return isolate()->builtins()->builtin( | 490 return isolate()->builtins()->KeyedLoadIC_NonStrictArguments(); |
| 472 Builtins::kKeyedLoadIC_NonStrictArguments); | |
| 473 } | 491 } |
| 474 | 492 |
| 475 static void Clear(Address address, Code* target); | 493 static void Clear(Address address, Code* target); |
| 476 | 494 |
| 477 friend class IC; | 495 friend class IC; |
| 478 }; | 496 }; |
| 479 | 497 |
| 480 | 498 |
| 481 class StoreIC: public IC { | 499 class StoreIC: public IC { |
| 482 public: | 500 public: |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 Builtins::kStoreIC_Megamorphic_Strict); | 545 Builtins::kStoreIC_Megamorphic_Strict); |
| 528 } | 546 } |
| 529 static Code* initialize_stub() { | 547 static Code* initialize_stub() { |
| 530 return Isolate::Current()->builtins()->builtin( | 548 return Isolate::Current()->builtins()->builtin( |
| 531 Builtins::kStoreIC_Initialize); | 549 Builtins::kStoreIC_Initialize); |
| 532 } | 550 } |
| 533 static Code* initialize_stub_strict() { | 551 static Code* initialize_stub_strict() { |
| 534 return Isolate::Current()->builtins()->builtin( | 552 return Isolate::Current()->builtins()->builtin( |
| 535 Builtins::kStoreIC_Initialize_Strict); | 553 Builtins::kStoreIC_Initialize_Strict); |
| 536 } | 554 } |
| 537 Code* global_proxy_stub() { | 555 Handle<Code> global_proxy_stub() { |
| 538 return isolate()->builtins()->builtin( | 556 return isolate()->builtins()->StoreIC_GlobalProxy(); |
| 539 Builtins::kStoreIC_GlobalProxy); | |
| 540 } | 557 } |
| 541 Code* global_proxy_stub_strict() { | 558 Handle<Code> global_proxy_stub_strict() { |
| 542 return isolate()->builtins()->builtin( | 559 return isolate()->builtins()->StoreIC_GlobalProxy_Strict(); |
| 543 Builtins::kStoreIC_GlobalProxy_Strict); | |
| 544 } | 560 } |
| 545 | 561 |
| 546 static void Clear(Address address, Code* target); | 562 static void Clear(Address address, Code* target); |
| 547 | 563 |
| 548 friend class IC; | 564 friend class IC; |
| 549 }; | 565 }; |
| 550 | 566 |
| 551 | 567 |
| 552 class KeyedStoreIC: public KeyedIC { | 568 class KeyedStoreIC: public KeyedIC { |
| 553 public: | 569 public: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 565 // Code generators for stub routines. Only called once at startup. | 581 // Code generators for stub routines. Only called once at startup. |
| 566 static void GenerateInitialize(MacroAssembler* masm) { | 582 static void GenerateInitialize(MacroAssembler* masm) { |
| 567 GenerateMiss(masm, false); | 583 GenerateMiss(masm, false); |
| 568 } | 584 } |
| 569 static void GenerateMiss(MacroAssembler* masm, bool force_generic); | 585 static void GenerateMiss(MacroAssembler* masm, bool force_generic); |
| 570 static void GenerateSlow(MacroAssembler* masm); | 586 static void GenerateSlow(MacroAssembler* masm); |
| 571 static void GenerateRuntimeSetProperty(MacroAssembler* masm, | 587 static void GenerateRuntimeSetProperty(MacroAssembler* masm, |
| 572 StrictModeFlag strict_mode); | 588 StrictModeFlag strict_mode); |
| 573 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); | 589 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); |
| 574 static void GenerateNonStrictArguments(MacroAssembler* masm); | 590 static void GenerateNonStrictArguments(MacroAssembler* masm); |
| 591 static void GenerateTransitionElementsSmiToDouble(MacroAssembler* masm); |
| 592 static void GenerateTransitionElementsDoubleToObject(MacroAssembler* masm); |
| 575 | 593 |
| 576 virtual MaybeObject* GetElementStubWithoutMapCheck( | 594 virtual Handle<Code> GetElementStubWithoutMapCheck( |
| 577 bool is_js_array, | 595 bool is_js_array, |
| 578 ElementsKind elements_kind); | 596 ElementsKind elements_kind); |
| 579 | 597 |
| 580 protected: | 598 protected: |
| 581 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } | 599 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } |
| 582 | 600 |
| 583 virtual MaybeObject* ComputePolymorphicStub( | 601 virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps, |
| 584 MapList* receiver_maps, | 602 StrictModeFlag strict_mode); |
| 585 StrictModeFlag strict_mode); | |
| 586 | 603 |
| 587 private: | 604 private: |
| 588 // Update the inline cache. | 605 // Update the inline cache. |
| 589 void UpdateCaches(LookupResult* lookup, | 606 void UpdateCaches(LookupResult* lookup, |
| 590 State state, | 607 State state, |
| 591 StrictModeFlag strict_mode, | 608 StrictModeFlag strict_mode, |
| 592 Handle<JSObject> receiver, | 609 Handle<JSObject> receiver, |
| 593 Handle<String> name, | 610 Handle<String> name, |
| 594 Handle<Object> value); | 611 Handle<Object> value); |
| 595 | 612 |
| 596 void set_target(Code* code) { | 613 void set_target(Code* code) { |
| 597 // Strict mode must be preserved across IC patching. | 614 // Strict mode must be preserved across IC patching. |
| 598 ASSERT((code->extra_ic_state() & kStrictMode) == | 615 ASSERT((code->extra_ic_state() & kStrictMode) == |
| 599 (target()->extra_ic_state() & kStrictMode)); | 616 (target()->extra_ic_state() & kStrictMode)); |
| 600 IC::set_target(code); | 617 IC::set_target(code); |
| 601 } | 618 } |
| 602 | 619 |
| 603 // Stub accessors. | 620 // Stub accessors. |
| 604 static Code* initialize_stub() { | 621 static Code* initialize_stub() { |
| 605 return Isolate::Current()->builtins()->builtin( | 622 return Isolate::Current()->builtins()->builtin( |
| 606 Builtins::kKeyedStoreIC_Initialize); | 623 Builtins::kKeyedStoreIC_Initialize); |
| 607 } | 624 } |
| 608 Code* megamorphic_stub() { | |
| 609 return isolate()->builtins()->builtin( | |
| 610 Builtins::kKeyedStoreIC_Generic); | |
| 611 } | |
| 612 static Code* initialize_stub_strict() { | 625 static Code* initialize_stub_strict() { |
| 613 return Isolate::Current()->builtins()->builtin( | 626 return Isolate::Current()->builtins()->builtin( |
| 614 Builtins::kKeyedStoreIC_Initialize_Strict); | 627 Builtins::kKeyedStoreIC_Initialize_Strict); |
| 615 } | 628 } |
| 616 Code* megamorphic_stub_strict() { | 629 Handle<Code> megamorphic_stub() { |
| 617 return isolate()->builtins()->builtin( | 630 return isolate()->builtins()->KeyedStoreIC_Generic(); |
| 618 Builtins::kKeyedStoreIC_Generic_Strict); | |
| 619 } | 631 } |
| 620 Code* generic_stub() { | 632 Handle<Code> megamorphic_stub_strict() { |
| 621 return isolate()->builtins()->builtin( | 633 return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); |
| 622 Builtins::kKeyedStoreIC_Generic); | |
| 623 } | 634 } |
| 624 Code* generic_stub_strict() { | 635 Handle<Code> generic_stub() { |
| 625 return isolate()->builtins()->builtin( | 636 return isolate()->builtins()->KeyedStoreIC_Generic(); |
| 626 Builtins::kKeyedStoreIC_Generic_Strict); | |
| 627 } | 637 } |
| 628 Code* non_strict_arguments_stub() { | 638 Handle<Code> generic_stub_strict() { |
| 629 return isolate()->builtins()->builtin( | 639 return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); |
| 630 Builtins::kKeyedStoreIC_NonStrictArguments); | 640 } |
| 641 Handle<Code> non_strict_arguments_stub() { |
| 642 return isolate()->builtins()->KeyedStoreIC_NonStrictArguments(); |
| 631 } | 643 } |
| 632 | 644 |
| 633 static void Clear(Address address, Code* target); | 645 static void Clear(Address address, Code* target); |
| 634 | 646 |
| 635 friend class IC; | 647 friend class IC; |
| 636 }; | 648 }; |
| 637 | 649 |
| 638 | 650 |
| 639 class UnaryOpIC: public IC { | 651 class UnaryOpIC: public IC { |
| 640 public: | 652 public: |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 void patch(Code* code); | 749 void patch(Code* code); |
| 738 }; | 750 }; |
| 739 | 751 |
| 740 | 752 |
| 741 // Helper for BinaryOpIC and CompareIC. | 753 // Helper for BinaryOpIC and CompareIC. |
| 742 void PatchInlinedSmiCode(Address address); | 754 void PatchInlinedSmiCode(Address address); |
| 743 | 755 |
| 744 } } // namespace v8::internal | 756 } } // namespace v8::internal |
| 745 | 757 |
| 746 #endif // V8_IC_H_ | 758 #endif // V8_IC_H_ |
| OLD | NEW |