| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 | 79 |
| 80 // The IC code is either invoked with no extra frames on the stack | 80 // The IC code is either invoked with no extra frames on the stack |
| 81 // or with a single extra frame for supporting calls. | 81 // or with a single extra frame for supporting calls. |
| 82 enum FrameDepth { | 82 enum FrameDepth { |
| 83 NO_EXTRA_FRAME = 0, | 83 NO_EXTRA_FRAME = 0, |
| 84 EXTRA_CALL_FRAME = 1 | 84 EXTRA_CALL_FRAME = 1 |
| 85 }; | 85 }; |
| 86 | 86 |
| 87 // Construct the IC structure with the given number of extra | 87 // Construct the IC structure with the given number of extra |
| 88 // JavaScript frames on the stack. | 88 // JavaScript frames on the stack. |
| 89 explicit IC(FrameDepth depth); | 89 IC(FrameDepth depth, Isolate* isolate); |
| 90 | 90 |
| 91 // Get the call-site target; used for determining the state. | 91 // Get the call-site target; used for determining the state. |
| 92 Code* target() { return GetTargetAtAddress(address()); } | 92 Code* target() { return GetTargetAtAddress(address()); } |
| 93 inline Address address(); | 93 inline Address address(); |
| 94 | 94 |
| 95 // Compute the current IC state based on the target stub, receiver and name. | 95 // Compute the current IC state based on the target stub, receiver and name. |
| 96 static State StateFrom(Code* target, Object* receiver, Object* name); | 96 static State StateFrom(Code* target, Object* receiver, Object* name); |
| 97 | 97 |
| 98 // Clear the inline cache to initial state. | 98 // Clear the inline cache to initial state. |
| 99 static void Clear(Address address); | 99 static void Clear(Address address); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 123 static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object, | 123 static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object, |
| 124 JSObject* holder); | 124 JSObject* holder); |
| 125 static inline InlineCacheHolderFlag GetCodeCacheForObject(JSObject* object, | 125 static inline InlineCacheHolderFlag GetCodeCacheForObject(JSObject* object, |
| 126 JSObject* holder); | 126 JSObject* holder); |
| 127 static inline JSObject* GetCodeCacheHolder(Object* object, | 127 static inline JSObject* GetCodeCacheHolder(Object* object, |
| 128 InlineCacheHolderFlag holder); | 128 InlineCacheHolderFlag holder); |
| 129 | 129 |
| 130 protected: | 130 protected: |
| 131 Address fp() const { return fp_; } | 131 Address fp() const { return fp_; } |
| 132 Address pc() const { return *pc_address_; } | 132 Address pc() const { return *pc_address_; } |
| 133 Isolate* isolate() const { return isolate_; } |
| 133 | 134 |
| 134 #ifdef ENABLE_DEBUGGER_SUPPORT | 135 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 135 // Computes the address in the original code when the code running is | 136 // Computes the address in the original code when the code running is |
| 136 // containing break points (calls to DebugBreakXXX builtins). | 137 // containing break points (calls to DebugBreakXXX builtins). |
| 137 Address OriginalCodeAddress(); | 138 Address OriginalCodeAddress(); |
| 138 #endif | 139 #endif |
| 139 | 140 |
| 140 // Set the call-site target. | 141 // Set the call-site target. |
| 141 void set_target(Code* code) { SetTargetAtAddress(address(), code); } | 142 void set_target(Code* code) { SetTargetAtAddress(address(), code); } |
| 142 | 143 |
| 143 #ifdef DEBUG | 144 #ifdef DEBUG |
| 144 static void TraceIC(const char* type, | 145 static void TraceIC(const char* type, |
| 145 Handle<Object> name, | 146 Handle<Object> name, |
| 146 State old_state, | 147 State old_state, |
| 147 Code* new_target, | 148 Code* new_target, |
| 148 const char* extra_info = ""); | 149 const char* extra_info = ""); |
| 149 #endif | 150 #endif |
| 150 | 151 |
| 151 static Failure* TypeError(const char* type, | 152 Failure* TypeError(const char* type, |
| 152 Handle<Object> object, | 153 Handle<Object> object, |
| 153 Handle<Object> key); | 154 Handle<Object> key); |
| 154 static Failure* ReferenceError(const char* type, Handle<String> name); | 155 Failure* ReferenceError(const char* type, Handle<String> name); |
| 155 | 156 |
| 156 // Access the target code for the given IC address. | 157 // Access the target code for the given IC address. |
| 157 static inline Code* GetTargetAtAddress(Address address); | 158 static inline Code* GetTargetAtAddress(Address address); |
| 158 static inline void SetTargetAtAddress(Address address, Code* target); | 159 static inline void SetTargetAtAddress(Address address, Code* target); |
| 159 | 160 |
| 160 private: | 161 private: |
| 161 // Frame pointer for the frame that uses (calls) the IC. | 162 // Frame pointer for the frame that uses (calls) the IC. |
| 162 Address fp_; | 163 Address fp_; |
| 163 | 164 |
| 164 // All access to the program counter of an IC structure is indirect | 165 // All access to the program counter of an IC structure is indirect |
| 165 // to make the code GC safe. This feature is crucial since | 166 // to make the code GC safe. This feature is crucial since |
| 166 // GetProperty and SetProperty are called and they in turn might | 167 // GetProperty and SetProperty are called and they in turn might |
| 167 // invoke the garbage collector. | 168 // invoke the garbage collector. |
| 168 Address* pc_address_; | 169 Address* pc_address_; |
| 169 | 170 |
| 171 Isolate* isolate_; |
| 172 |
| 170 DISALLOW_IMPLICIT_CONSTRUCTORS(IC); | 173 DISALLOW_IMPLICIT_CONSTRUCTORS(IC); |
| 171 }; | 174 }; |
| 172 | 175 |
| 173 | 176 |
| 174 // An IC_Utility encapsulates IC::UtilityId. It exists mainly because you | 177 // An IC_Utility encapsulates IC::UtilityId. It exists mainly because you |
| 175 // cannot make forward declarations to an enum. | 178 // cannot make forward declarations to an enum. |
| 176 class IC_Utility { | 179 class IC_Utility { |
| 177 public: | 180 public: |
| 178 explicit IC_Utility(IC::UtilityId id) | 181 explicit IC_Utility(IC::UtilityId id) |
| 179 : address_(IC::AddressFromUtilityId(id)), id_(id) {} | 182 : address_(IC::AddressFromUtilityId(id)), id_(id) {} |
| 180 | 183 |
| 181 Address address() const { return address_; } | 184 Address address() const { return address_; } |
| 182 | 185 |
| 183 IC::UtilityId id() const { return id_; } | 186 IC::UtilityId id() const { return id_; } |
| 184 private: | 187 private: |
| 185 Address address_; | 188 Address address_; |
| 186 IC::UtilityId id_; | 189 IC::UtilityId id_; |
| 187 }; | 190 }; |
| 188 | 191 |
| 189 | 192 |
| 190 class CallICBase: public IC { | 193 class CallICBase: public IC { |
| 191 protected: | 194 protected: |
| 192 explicit CallICBase(Code::Kind kind) : IC(EXTRA_CALL_FRAME), kind_(kind) {} | 195 CallICBase(Code::Kind kind, Isolate* isolate) |
| 196 : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {} |
| 193 | 197 |
| 194 public: | 198 public: |
| 195 MUST_USE_RESULT MaybeObject* LoadFunction(State state, | 199 MUST_USE_RESULT MaybeObject* LoadFunction(State state, |
| 196 Code::ExtraICState extra_ic_state, | 200 Code::ExtraICState extra_ic_state, |
| 197 Handle<Object> object, | 201 Handle<Object> object, |
| 198 Handle<String> name); | 202 Handle<String> name); |
| 199 | 203 |
| 200 protected: | 204 protected: |
| 201 Code::Kind kind_; | 205 Code::Kind kind_; |
| 202 | 206 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 226 | 230 |
| 227 void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object); | 231 void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object); |
| 228 | 232 |
| 229 static void Clear(Address address, Code* target); | 233 static void Clear(Address address, Code* target); |
| 230 friend class IC; | 234 friend class IC; |
| 231 }; | 235 }; |
| 232 | 236 |
| 233 | 237 |
| 234 class CallIC: public CallICBase { | 238 class CallIC: public CallICBase { |
| 235 public: | 239 public: |
| 236 CallIC() : CallICBase(Code::CALL_IC) { ASSERT(target()->is_call_stub()); } | 240 explicit CallIC(Isolate* isolate) : CallICBase(Code::CALL_IC, isolate) { |
| 241 ASSERT(target()->is_call_stub()); |
| 242 } |
| 237 | 243 |
| 238 // Code generator routines. | 244 // Code generator routines. |
| 239 static void GenerateInitialize(MacroAssembler* masm, int argc) { | 245 static void GenerateInitialize(MacroAssembler* masm, int argc) { |
| 240 GenerateMiss(masm, argc); | 246 GenerateMiss(masm, argc); |
| 241 } | 247 } |
| 242 static void GenerateMiss(MacroAssembler* masm, int argc); | 248 static void GenerateMiss(MacroAssembler* masm, int argc); |
| 243 static void GenerateMegamorphic(MacroAssembler* masm, int argc); | 249 static void GenerateMegamorphic(MacroAssembler* masm, int argc); |
| 244 static void GenerateNormal(MacroAssembler* masm, int argc); | 250 static void GenerateNormal(MacroAssembler* masm, int argc); |
| 245 }; | 251 }; |
| 246 | 252 |
| 247 | 253 |
| 248 class KeyedCallIC: public CallICBase { | 254 class KeyedCallIC: public CallICBase { |
| 249 public: | 255 public: |
| 250 KeyedCallIC() : CallICBase(Code::KEYED_CALL_IC) { | 256 explicit KeyedCallIC(Isolate* isolate) |
| 257 : CallICBase(Code::KEYED_CALL_IC, isolate) { |
| 251 ASSERT(target()->is_keyed_call_stub()); | 258 ASSERT(target()->is_keyed_call_stub()); |
| 252 } | 259 } |
| 253 | 260 |
| 254 MUST_USE_RESULT MaybeObject* LoadFunction(State state, | 261 MUST_USE_RESULT MaybeObject* LoadFunction(State state, |
| 255 Handle<Object> object, | 262 Handle<Object> object, |
| 256 Handle<Object> key); | 263 Handle<Object> key); |
| 257 | 264 |
| 258 // Code generator routines. | 265 // Code generator routines. |
| 259 static void GenerateInitialize(MacroAssembler* masm, int argc) { | 266 static void GenerateInitialize(MacroAssembler* masm, int argc) { |
| 260 GenerateMiss(masm, argc); | 267 GenerateMiss(masm, argc); |
| 261 } | 268 } |
| 262 static void GenerateMiss(MacroAssembler* masm, int argc); | 269 static void GenerateMiss(MacroAssembler* masm, int argc); |
| 263 static void GenerateMegamorphic(MacroAssembler* masm, int argc); | 270 static void GenerateMegamorphic(MacroAssembler* masm, int argc); |
| 264 static void GenerateNormal(MacroAssembler* masm, int argc); | 271 static void GenerateNormal(MacroAssembler* masm, int argc); |
| 265 }; | 272 }; |
| 266 | 273 |
| 267 | 274 |
| 268 class LoadIC: public IC { | 275 class LoadIC: public IC { |
| 269 public: | 276 public: |
| 270 LoadIC() : IC(NO_EXTRA_FRAME) { ASSERT(target()->is_load_stub()); } | 277 explicit LoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { |
| 278 ASSERT(target()->is_load_stub()); |
| 279 } |
| 271 | 280 |
| 272 MUST_USE_RESULT MaybeObject* Load(State state, | 281 MUST_USE_RESULT MaybeObject* Load(State state, |
| 273 Handle<Object> object, | 282 Handle<Object> object, |
| 274 Handle<String> name); | 283 Handle<String> name); |
| 275 | 284 |
| 276 // Code generator routines. | 285 // Code generator routines. |
| 277 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 286 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } |
| 278 static void GeneratePreMonomorphic(MacroAssembler* masm) { | 287 static void GeneratePreMonomorphic(MacroAssembler* masm) { |
| 279 GenerateMiss(masm); | 288 GenerateMiss(masm); |
| 280 } | 289 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 298 | 307 |
| 299 private: | 308 private: |
| 300 // Update the inline cache and the global stub cache based on the | 309 // Update the inline cache and the global stub cache based on the |
| 301 // lookup result. | 310 // lookup result. |
| 302 void UpdateCaches(LookupResult* lookup, | 311 void UpdateCaches(LookupResult* lookup, |
| 303 State state, | 312 State state, |
| 304 Handle<Object> object, | 313 Handle<Object> object, |
| 305 Handle<String> name); | 314 Handle<String> name); |
| 306 | 315 |
| 307 // Stub accessors. | 316 // Stub accessors. |
| 308 static Code* megamorphic_stub() { | 317 Code* megamorphic_stub() { |
| 309 return Builtins::builtin(Builtins::LoadIC_Megamorphic); | 318 return isolate()->builtins()->builtin( |
| 319 Builtins::LoadIC_Megamorphic); |
| 310 } | 320 } |
| 311 static Code* initialize_stub() { | 321 static Code* initialize_stub() { |
| 312 return Builtins::builtin(Builtins::LoadIC_Initialize); | 322 return Isolate::Current()->builtins()->builtin( |
| 323 Builtins::LoadIC_Initialize); |
| 313 } | 324 } |
| 314 static Code* pre_monomorphic_stub() { | 325 Code* pre_monomorphic_stub() { |
| 315 return Builtins::builtin(Builtins::LoadIC_PreMonomorphic); | 326 return isolate()->builtins()->builtin( |
| 327 Builtins::LoadIC_PreMonomorphic); |
| 316 } | 328 } |
| 317 | 329 |
| 318 static void Clear(Address address, Code* target); | 330 static void Clear(Address address, Code* target); |
| 319 | 331 |
| 320 static bool PatchInlinedLoad(Address address, Object* map, int index); | 332 static bool PatchInlinedLoad(Address address, Object* map, int index); |
| 321 | 333 |
| 322 static bool PatchInlinedContextualLoad(Address address, | 334 static bool PatchInlinedContextualLoad(Address address, |
| 323 Object* map, | 335 Object* map, |
| 324 Object* cell, | 336 Object* cell, |
| 325 bool is_dont_delete); | 337 bool is_dont_delete); |
| 326 | 338 |
| 327 friend class IC; | 339 friend class IC; |
| 328 }; | 340 }; |
| 329 | 341 |
| 330 | 342 |
| 331 class KeyedLoadIC: public IC { | 343 class KeyedLoadIC: public IC { |
| 332 public: | 344 public: |
| 333 KeyedLoadIC() : IC(NO_EXTRA_FRAME) { ASSERT(target()->is_keyed_load_stub()); } | 345 explicit KeyedLoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { |
| 346 ASSERT(target()->is_keyed_load_stub()); |
| 347 } |
| 334 | 348 |
| 335 MUST_USE_RESULT MaybeObject* Load(State state, | 349 MUST_USE_RESULT MaybeObject* Load(State state, |
| 336 Handle<Object> object, | 350 Handle<Object> object, |
| 337 Handle<Object> key); | 351 Handle<Object> key); |
| 338 | 352 |
| 339 // Code generator routines. | 353 // Code generator routines. |
| 340 static void GenerateMiss(MacroAssembler* masm); | 354 static void GenerateMiss(MacroAssembler* masm); |
| 341 static void GenerateRuntimeGetProperty(MacroAssembler* masm); | 355 static void GenerateRuntimeGetProperty(MacroAssembler* masm); |
| 342 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 356 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } |
| 343 static void GeneratePreMonomorphic(MacroAssembler* masm) { | 357 static void GeneratePreMonomorphic(MacroAssembler* masm) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 360 | 374 |
| 361 private: | 375 private: |
| 362 // Update the inline cache. | 376 // Update the inline cache. |
| 363 void UpdateCaches(LookupResult* lookup, | 377 void UpdateCaches(LookupResult* lookup, |
| 364 State state, | 378 State state, |
| 365 Handle<Object> object, | 379 Handle<Object> object, |
| 366 Handle<String> name); | 380 Handle<String> name); |
| 367 | 381 |
| 368 // Stub accessors. | 382 // Stub accessors. |
| 369 static Code* initialize_stub() { | 383 static Code* initialize_stub() { |
| 370 return Builtins::builtin(Builtins::KeyedLoadIC_Initialize); | 384 return Isolate::Current()->builtins()->builtin( |
| 385 Builtins::KeyedLoadIC_Initialize); |
| 371 } | 386 } |
| 372 static Code* megamorphic_stub() { | 387 Code* megamorphic_stub() { |
| 373 return Builtins::builtin(Builtins::KeyedLoadIC_Generic); | 388 return isolate()->builtins()->builtin( |
| 389 Builtins::KeyedLoadIC_Generic); |
| 374 } | 390 } |
| 375 static Code* generic_stub() { | 391 Code* generic_stub() { |
| 376 return Builtins::builtin(Builtins::KeyedLoadIC_Generic); | 392 return isolate()->builtins()->builtin( |
| 393 Builtins::KeyedLoadIC_Generic); |
| 377 } | 394 } |
| 378 static Code* pre_monomorphic_stub() { | 395 Code* pre_monomorphic_stub() { |
| 379 return Builtins::builtin(Builtins::KeyedLoadIC_PreMonomorphic); | 396 return isolate()->builtins()->builtin( |
| 397 Builtins::KeyedLoadIC_PreMonomorphic); |
| 380 } | 398 } |
| 381 static Code* string_stub() { | 399 Code* string_stub() { |
| 382 return Builtins::builtin(Builtins::KeyedLoadIC_String); | 400 return isolate()->builtins()->builtin( |
| 401 Builtins::KeyedLoadIC_String); |
| 383 } | 402 } |
| 384 | 403 |
| 385 static Code* indexed_interceptor_stub() { | 404 Code* indexed_interceptor_stub() { |
| 386 return Builtins::builtin(Builtins::KeyedLoadIC_IndexedInterceptor); | 405 return isolate()->builtins()->builtin( |
| 406 Builtins::KeyedLoadIC_IndexedInterceptor); |
| 387 } | 407 } |
| 388 | 408 |
| 389 static void Clear(Address address, Code* target); | 409 static void Clear(Address address, Code* target); |
| 390 | 410 |
| 391 // Support for patching the map that is checked in an inlined | 411 // Support for patching the map that is checked in an inlined |
| 392 // version of keyed load. | 412 // version of keyed load. |
| 393 static bool PatchInlinedLoad(Address address, Object* map); | 413 static bool PatchInlinedLoad(Address address, Object* map); |
| 394 | 414 |
| 395 friend class IC; | 415 friend class IC; |
| 396 }; | 416 }; |
| 397 | 417 |
| 398 | 418 |
| 399 class StoreIC: public IC { | 419 class StoreIC: public IC { |
| 400 public: | 420 public: |
| 401 StoreIC() : IC(NO_EXTRA_FRAME) { ASSERT(target()->is_store_stub()); } | 421 explicit StoreIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { |
| 422 ASSERT(target()->is_store_stub()); |
| 423 } |
| 402 | 424 |
| 403 MUST_USE_RESULT MaybeObject* Store(State state, | 425 MUST_USE_RESULT MaybeObject* Store(State state, |
| 404 StrictModeFlag strict_mode, | 426 StrictModeFlag strict_mode, |
| 405 Handle<Object> object, | 427 Handle<Object> object, |
| 406 Handle<String> name, | 428 Handle<String> name, |
| 407 Handle<Object> value); | 429 Handle<Object> value); |
| 408 | 430 |
| 409 // Code generators for stub routines. Only called once at startup. | 431 // Code generators for stub routines. Only called once at startup. |
| 410 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 432 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } |
| 411 static void GenerateMiss(MacroAssembler* masm); | 433 static void GenerateMiss(MacroAssembler* masm); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 434 Handle<Object> value); | 456 Handle<Object> value); |
| 435 | 457 |
| 436 void set_target(Code* code) { | 458 void set_target(Code* code) { |
| 437 // Strict mode must be preserved across IC patching. | 459 // Strict mode must be preserved across IC patching. |
| 438 ASSERT((code->extra_ic_state() & kStrictMode) == | 460 ASSERT((code->extra_ic_state() & kStrictMode) == |
| 439 (target()->extra_ic_state() & kStrictMode)); | 461 (target()->extra_ic_state() & kStrictMode)); |
| 440 IC::set_target(code); | 462 IC::set_target(code); |
| 441 } | 463 } |
| 442 | 464 |
| 443 // Stub accessors. | 465 // Stub accessors. |
| 444 static Code* megamorphic_stub() { | 466 Code* megamorphic_stub() { |
| 445 return Builtins::builtin(Builtins::StoreIC_Megamorphic); | 467 return isolate()->builtins()->builtin( |
| 468 Builtins::StoreIC_Megamorphic); |
| 446 } | 469 } |
| 447 static Code* megamorphic_stub_strict() { | 470 Code* megamorphic_stub_strict() { |
| 448 return Builtins::builtin(Builtins::StoreIC_Megamorphic_Strict); | 471 return isolate()->builtins()->builtin( |
| 472 Builtins::StoreIC_Megamorphic_Strict); |
| 449 } | 473 } |
| 450 static Code* initialize_stub() { | 474 static Code* initialize_stub() { |
| 451 return Builtins::builtin(Builtins::StoreIC_Initialize); | 475 return Isolate::Current()->builtins()->builtin( |
| 476 Builtins::StoreIC_Initialize); |
| 452 } | 477 } |
| 453 static Code* initialize_stub_strict() { | 478 static Code* initialize_stub_strict() { |
| 454 return Builtins::builtin(Builtins::StoreIC_Initialize_Strict); | 479 return Isolate::Current()->builtins()->builtin( |
| 480 Builtins::StoreIC_Initialize_Strict); |
| 455 } | 481 } |
| 456 static Code* global_proxy_stub() { | 482 Code* global_proxy_stub() { |
| 457 return Builtins::builtin(Builtins::StoreIC_GlobalProxy); | 483 return isolate()->builtins()->builtin( |
| 484 Builtins::StoreIC_GlobalProxy); |
| 458 } | 485 } |
| 459 static Code* global_proxy_stub_strict() { | 486 Code* global_proxy_stub_strict() { |
| 460 return Builtins::builtin(Builtins::StoreIC_GlobalProxy_Strict); | 487 return isolate()->builtins()->builtin( |
| 488 Builtins::StoreIC_GlobalProxy_Strict); |
| 461 } | 489 } |
| 462 | 490 |
| 463 static void Clear(Address address, Code* target); | 491 static void Clear(Address address, Code* target); |
| 464 | 492 |
| 465 // Support for patching the index and the map that is checked in an | 493 // Support for patching the index and the map that is checked in an |
| 466 // inlined version of the named store. | 494 // inlined version of the named store. |
| 467 static bool PatchInlinedStore(Address address, Object* map, int index); | 495 static bool PatchInlinedStore(Address address, Object* map, int index); |
| 468 | 496 |
| 469 friend class IC; | 497 friend class IC; |
| 470 }; | 498 }; |
| 471 | 499 |
| 472 | 500 |
| 473 class KeyedStoreIC: public IC { | 501 class KeyedStoreIC: public IC { |
| 474 public: | 502 public: |
| 475 KeyedStoreIC() : IC(NO_EXTRA_FRAME) { } | 503 explicit KeyedStoreIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { } |
| 476 | 504 |
| 477 MUST_USE_RESULT MaybeObject* Store(State state, | 505 MUST_USE_RESULT MaybeObject* Store(State state, |
| 478 StrictModeFlag strict_mode, | 506 StrictModeFlag strict_mode, |
| 479 Handle<Object> object, | 507 Handle<Object> object, |
| 480 Handle<Object> name, | 508 Handle<Object> name, |
| 481 Handle<Object> value); | 509 Handle<Object> value); |
| 482 | 510 |
| 483 // Code generators for stub routines. Only called once at startup. | 511 // Code generators for stub routines. Only called once at startup. |
| 484 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 512 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } |
| 485 static void GenerateMiss(MacroAssembler* masm); | 513 static void GenerateMiss(MacroAssembler* masm); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 504 | 532 |
| 505 void set_target(Code* code) { | 533 void set_target(Code* code) { |
| 506 // Strict mode must be preserved across IC patching. | 534 // Strict mode must be preserved across IC patching. |
| 507 ASSERT((code->extra_ic_state() & kStrictMode) == | 535 ASSERT((code->extra_ic_state() & kStrictMode) == |
| 508 (target()->extra_ic_state() & kStrictMode)); | 536 (target()->extra_ic_state() & kStrictMode)); |
| 509 IC::set_target(code); | 537 IC::set_target(code); |
| 510 } | 538 } |
| 511 | 539 |
| 512 // Stub accessors. | 540 // Stub accessors. |
| 513 static Code* initialize_stub() { | 541 static Code* initialize_stub() { |
| 514 return Builtins::builtin(Builtins::KeyedStoreIC_Initialize); | 542 return Isolate::Current()->builtins()->builtin( |
| 543 Builtins::KeyedStoreIC_Initialize); |
| 544 } |
| 545 Code* megamorphic_stub() { |
| 546 return isolate()->builtins()->builtin( |
| 547 Builtins::KeyedStoreIC_Generic); |
| 515 } | 548 } |
| 516 static Code* initialize_stub_strict() { | 549 static Code* initialize_stub_strict() { |
| 517 return Builtins::builtin(Builtins::KeyedStoreIC_Initialize_Strict); | 550 return Isolate::Current()->builtins()->builtin( |
| 551 Builtins::KeyedStoreIC_Initialize_Strict); |
| 518 } | 552 } |
| 519 static Code* megamorphic_stub() { | 553 Code* megamorphic_stub_strict() { |
| 520 return Builtins::builtin(Builtins::KeyedStoreIC_Generic); | 554 return isolate()->builtins()->builtin( |
| 555 Builtins::KeyedStoreIC_Generic_Strict); |
| 521 } | 556 } |
| 522 static Code* megamorphic_stub_strict() { | 557 Code* generic_stub() { |
| 523 return Builtins::builtin(Builtins::KeyedStoreIC_Generic_Strict); | 558 return isolate()->builtins()->builtin( |
| 559 Builtins::KeyedStoreIC_Generic); |
| 524 } | 560 } |
| 525 static Code* generic_stub() { | 561 Code* generic_stub_strict() { |
| 526 return Builtins::builtin(Builtins::KeyedStoreIC_Generic); | 562 return isolate()->builtins()->builtin( |
| 527 } | 563 Builtins::KeyedStoreIC_Generic_Strict); |
| 528 static Code* generic_stub_strict() { | |
| 529 return Builtins::builtin(Builtins::KeyedStoreIC_Generic_Strict); | |
| 530 } | 564 } |
| 531 | 565 |
| 532 static void Clear(Address address, Code* target); | 566 static void Clear(Address address, Code* target); |
| 533 | 567 |
| 534 // Support for patching the map that is checked in an inlined | 568 // Support for patching the map that is checked in an inlined |
| 535 // version of keyed store. | 569 // version of keyed store. |
| 536 // The address is the patch point for the IC call | 570 // The address is the patch point for the IC call |
| 537 // (Assembler::kCallTargetAddressOffset before the end of | 571 // (Assembler::kCallTargetAddressOffset before the end of |
| 538 // the call/return address). | 572 // the call/return address). |
| 539 // The map is the new map that the inlined code should check against. | 573 // The map is the new map that the inlined code should check against. |
| 540 static bool PatchInlinedStore(Address address, Object* map); | 574 static bool PatchInlinedStore(Address address, Object* map); |
| 541 | 575 |
| 542 friend class IC; | 576 friend class IC; |
| 543 }; | 577 }; |
| 544 | 578 |
| 545 | 579 |
| 546 class BinaryOpIC: public IC { | 580 class BinaryOpIC: public IC { |
| 547 public: | 581 public: |
| 548 | 582 |
| 549 enum TypeInfo { | 583 enum TypeInfo { |
| 550 UNINIT_OR_SMI, | 584 UNINIT_OR_SMI, |
| 551 DEFAULT, // Initial state. When first executed, patches to one | 585 DEFAULT, // Initial state. When first executed, patches to one |
| 552 // of the following states depending on the operands types. | 586 // of the following states depending on the operands types. |
| 553 HEAP_NUMBERS, // Both arguments are HeapNumbers. | 587 HEAP_NUMBERS, // Both arguments are HeapNumbers. |
| 554 STRINGS, // At least one of the arguments is String. | 588 STRINGS, // At least one of the arguments is String. |
| 555 GENERIC // Non-specialized case (processes any type combination). | 589 GENERIC // Non-specialized case (processes any type combination). |
| 556 }; | 590 }; |
| 557 | 591 |
| 558 BinaryOpIC() : IC(NO_EXTRA_FRAME) { } | 592 explicit BinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { } |
| 559 | 593 |
| 560 void patch(Code* code); | 594 void patch(Code* code); |
| 561 | 595 |
| 562 static const char* GetName(TypeInfo type_info); | 596 static const char* GetName(TypeInfo type_info); |
| 563 | 597 |
| 564 static State ToState(TypeInfo type_info); | 598 static State ToState(TypeInfo type_info); |
| 565 | 599 |
| 566 static TypeInfo GetTypeInfo(Object* left, Object* right); | 600 static TypeInfo GetTypeInfo(Object* left, Object* right); |
| 567 }; | 601 }; |
| 568 | 602 |
| 569 | 603 |
| 570 // Type Recording BinaryOpIC, that records the types of the inputs and outputs. | 604 // Type Recording BinaryOpIC, that records the types of the inputs and outputs. |
| 571 class TRBinaryOpIC: public IC { | 605 class TRBinaryOpIC: public IC { |
| 572 public: | 606 public: |
| 573 | 607 |
| 574 enum TypeInfo { | 608 enum TypeInfo { |
| 575 UNINITIALIZED, | 609 UNINITIALIZED, |
| 576 SMI, | 610 SMI, |
| 577 INT32, | 611 INT32, |
| 578 HEAP_NUMBER, | 612 HEAP_NUMBER, |
| 579 STRING, // Only used for addition operation. At least one string operand. | 613 STRING, // Only used for addition operation. At least one string operand. |
| 580 GENERIC | 614 GENERIC |
| 581 }; | 615 }; |
| 582 | 616 |
| 583 TRBinaryOpIC() : IC(NO_EXTRA_FRAME) { } | 617 explicit TRBinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { } |
| 584 | 618 |
| 585 void patch(Code* code); | 619 void patch(Code* code); |
| 586 | 620 |
| 587 static const char* GetName(TypeInfo type_info); | 621 static const char* GetName(TypeInfo type_info); |
| 588 | 622 |
| 589 static State ToState(TypeInfo type_info); | 623 static State ToState(TypeInfo type_info); |
| 590 | 624 |
| 591 static TypeInfo GetTypeInfo(Handle<Object> left, Handle<Object> right); | 625 static TypeInfo GetTypeInfo(Handle<Object> left, Handle<Object> right); |
| 592 | 626 |
| 593 static TypeInfo JoinTypes(TypeInfo x, TypeInfo y); | 627 static TypeInfo JoinTypes(TypeInfo x, TypeInfo y); |
| 594 }; | 628 }; |
| 595 | 629 |
| 596 | 630 |
| 597 class CompareIC: public IC { | 631 class CompareIC: public IC { |
| 598 public: | 632 public: |
| 599 enum State { | 633 enum State { |
| 600 UNINITIALIZED, | 634 UNINITIALIZED, |
| 601 SMIS, | 635 SMIS, |
| 602 HEAP_NUMBERS, | 636 HEAP_NUMBERS, |
| 603 OBJECTS, | 637 OBJECTS, |
| 604 GENERIC | 638 GENERIC |
| 605 }; | 639 }; |
| 606 | 640 |
| 607 explicit CompareIC(Token::Value op) : IC(EXTRA_CALL_FRAME), op_(op) { } | 641 CompareIC(Isolate* isolate, Token::Value op) |
| 642 : IC(EXTRA_CALL_FRAME, isolate), op_(op) { } |
| 608 | 643 |
| 609 // Update the inline cache for the given operands. | 644 // Update the inline cache for the given operands. |
| 610 void UpdateCaches(Handle<Object> x, Handle<Object> y); | 645 void UpdateCaches(Handle<Object> x, Handle<Object> y); |
| 611 | 646 |
| 612 // Factory method for getting an uninitialized compare stub. | 647 // Factory method for getting an uninitialized compare stub. |
| 613 static Handle<Code> GetUninitialized(Token::Value op); | 648 static Handle<Code> GetUninitialized(Token::Value op); |
| 614 | 649 |
| 615 // Helper function for computing the condition for a compare operation. | 650 // Helper function for computing the condition for a compare operation. |
| 616 static Condition ComputeCondition(Token::Value op); | 651 static Condition ComputeCondition(Token::Value op); |
| 617 | 652 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 630 | 665 |
| 631 Token::Value op_; | 666 Token::Value op_; |
| 632 }; | 667 }; |
| 633 | 668 |
| 634 // Helper for TRBinaryOpIC and CompareIC. | 669 // Helper for TRBinaryOpIC and CompareIC. |
| 635 void PatchInlinedSmiCode(Address address); | 670 void PatchInlinedSmiCode(Address address); |
| 636 | 671 |
| 637 } } // namespace v8::internal | 672 } } // namespace v8::internal |
| 638 | 673 |
| 639 #endif // V8_IC_H_ | 674 #endif // V8_IC_H_ |
| OLD | NEW |