| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 | 102 |
| 103 Handle<JSObject> StubCache::StubHolder(Handle<JSObject> receiver, | 103 Handle<JSObject> StubCache::StubHolder(Handle<JSObject> receiver, |
| 104 Handle<JSObject> holder) { | 104 Handle<JSObject> holder) { |
| 105 InlineCacheHolderFlag cache_holder = | 105 InlineCacheHolderFlag cache_holder = |
| 106 IC::GetCodeCacheForObject(*receiver, *holder); | 106 IC::GetCodeCacheForObject(*receiver, *holder); |
| 107 return Handle<JSObject>(IC::GetCodeCacheHolder( | 107 return Handle<JSObject>(IC::GetCodeCacheHolder( |
| 108 isolate_, *receiver, cache_holder)); | 108 isolate_, *receiver, cache_holder)); |
| 109 } | 109 } |
| 110 | 110 |
| 111 | 111 |
| 112 Handle<Code> StubCache::FindStub(Handle<Name> name, | 112 Handle<Code> StubCache::FindIC(Handle<Name> name, |
| 113 Handle<JSObject> stub_holder, | 113 Handle<JSObject> stub_holder, |
| 114 Code::Kind kind, | 114 Code::Kind kind, |
| 115 Code::StubType type, | 115 Code::StubType type) { |
| 116 Code::IcFragment fragment) { | 116 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 117 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, fragment, type); | 117 kind, Code::kNoExtraICState, type); |
| 118 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), | 118 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), |
| 119 isolate_); | 119 isolate_); |
| 120 if (probe->IsCode()) return Handle<Code>::cast(probe); | 120 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 121 return Handle<Code>::null(); | 121 return Handle<Code>::null(); |
| 122 } | 122 } |
| 123 | 123 |
| 124 | 124 |
| 125 Handle<Code> StubCache::FindHandler(Handle<Name> name, | 125 Handle<Code> StubCache::FindStub(Handle<Name> name, |
| 126 Handle<JSObject> handler_holder, | 126 Handle<JSObject> stub_holder, |
| 127 Code::Kind kind, | 127 Code::Kind kind, |
| 128 Code::StubType type) { | 128 Code::StubType type) { |
| 129 return FindStub(name, handler_holder, kind, type, Code::HANDLER_FRAGMENT); | 129 ASSERT(type != Code::NORMAL); |
| 130 int extra_flags = -1; |
| 131 if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC) { |
| 132 extra_flags = kind; |
| 133 kind = Code::STUB; |
| 134 } |
| 135 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 136 kind, Code::kNoExtraICState, type, extra_flags); |
| 137 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), |
| 138 isolate_); |
| 139 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 140 return Handle<Code>::null(); |
| 130 } | 141 } |
| 131 | 142 |
| 132 | 143 |
| 133 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<JSObject> receiver, | 144 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<JSObject> receiver, |
| 134 Handle<Code> handler, | 145 Handle<Code> handler, |
| 135 Handle<Name> name) { | 146 Handle<Name> name) { |
| 136 Handle<Code> ic = FindStub(name, receiver, Code::LOAD_IC, | 147 Handle<Code> ic = FindIC(name, receiver, Code::LOAD_IC, handler->type()); |
| 137 handler->type(), Code::IC_FRAGMENT); | |
| 138 if (!ic.is_null()) return ic; | 148 if (!ic.is_null()) return ic; |
| 139 | 149 |
| 140 LoadStubCompiler ic_compiler(isolate()); | 150 LoadStubCompiler ic_compiler(isolate()); |
| 141 ic = ic_compiler.CompileMonomorphicIC( | 151 ic = ic_compiler.CompileMonomorphicIC( |
| 142 Handle<Map>(receiver->map()), handler, name); | 152 Handle<Map>(receiver->map()), handler, name); |
| 143 | 153 |
| 144 JSObject::UpdateMapCodeCache(receiver, name, ic); | 154 JSObject::UpdateMapCodeCache(receiver, name, ic); |
| 145 return ic; | 155 return ic; |
| 146 } | 156 } |
| 147 | 157 |
| 148 | 158 |
| 149 Handle<Code> StubCache::ComputeKeyedMonomorphicIC(Handle<JSObject> receiver, | 159 Handle<Code> StubCache::ComputeKeyedMonomorphicIC(Handle<JSObject> receiver, |
| 150 Handle<Code> handler, | 160 Handle<Code> handler, |
| 151 Handle<Name> name) { | 161 Handle<Name> name) { |
| 152 Handle<Code> ic = FindStub(name, receiver, Code::KEYED_LOAD_IC, | 162 Handle<Code> ic = FindIC( |
| 153 handler->type(), Code::IC_FRAGMENT); | 163 name, receiver, Code::KEYED_LOAD_IC, handler->type()); |
| 154 if (!ic.is_null()) return ic; | 164 if (!ic.is_null()) return ic; |
| 155 | 165 |
| 156 KeyedLoadStubCompiler ic_compiler(isolate()); | 166 KeyedLoadStubCompiler ic_compiler(isolate()); |
| 157 ic = ic_compiler.CompileMonomorphicIC( | 167 ic = ic_compiler.CompileMonomorphicIC( |
| 158 Handle<Map>(receiver->map()), handler, name); | 168 Handle<Map>(receiver->map()), handler, name); |
| 159 | 169 |
| 160 JSObject::UpdateMapCodeCache(receiver, name, ic); | 170 JSObject::UpdateMapCodeCache(receiver, name, ic); |
| 161 return ic; | 171 return ic; |
| 162 } | 172 } |
| 163 | 173 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 180 if (current->IsGlobalObject()) { | 190 if (current->IsGlobalObject()) { |
| 181 global = Handle<GlobalObject>::cast(current); | 191 global = Handle<GlobalObject>::cast(current); |
| 182 cache_name = name; | 192 cache_name = name; |
| 183 } else if (!current->HasFastProperties()) { | 193 } else if (!current->HasFastProperties()) { |
| 184 cache_name = name; | 194 cache_name = name; |
| 185 } | 195 } |
| 186 } while (!next->IsNull()); | 196 } while (!next->IsNull()); |
| 187 | 197 |
| 188 // Compile the stub that is either shared for all names or | 198 // Compile the stub that is either shared for all names or |
| 189 // name specific if there are global objects involved. | 199 // name specific if there are global objects involved. |
| 190 Handle<Code> handler = FindHandler( | 200 Handle<Code> handler = FindStub( |
| 191 cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT); | 201 cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT); |
| 192 if (!handler.is_null()) return handler; | 202 if (!handler.is_null()) return handler; |
| 193 | 203 |
| 194 LoadStubCompiler compiler(isolate_); | 204 LoadStubCompiler compiler(isolate_); |
| 195 handler = | 205 handler = |
| 196 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); | 206 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); |
| 197 JSObject::UpdateMapCodeCache(receiver, cache_name, handler); | 207 JSObject::UpdateMapCodeCache(receiver, cache_name, handler); |
| 198 return handler; | 208 return handler; |
| 199 } | 209 } |
| 200 | 210 |
| 201 | 211 |
| 202 Handle<Code> StubCache::ComputeLoadField(Handle<Name> name, | 212 Handle<Code> StubCache::ComputeLoadField(Handle<Name> name, |
| 203 Handle<JSObject> receiver, | 213 Handle<JSObject> receiver, |
| 204 Handle<JSObject> holder, | 214 Handle<JSObject> holder, |
| 205 PropertyIndex field) { | 215 PropertyIndex field) { |
| 206 if (receiver.is_identical_to(holder)) { | 216 if (receiver.is_identical_to(holder)) { |
| 207 LoadFieldStub stub(LoadStubCompiler::receiver(), | 217 LoadFieldStub stub(LoadStubCompiler::receiver(), |
| 208 field.is_inobject(holder), | 218 field.is_inobject(holder), |
| 209 field.translate(holder)); | 219 field.translate(holder)); |
| 210 return stub.GetCode(isolate()); | 220 return stub.GetCode(isolate()); |
| 211 } | 221 } |
| 212 | 222 |
| 213 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 223 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
| 214 Handle<Code> stub = FindHandler( | 224 Handle<Code> stub = FindStub( |
| 215 name, stub_holder, Code::LOAD_IC, Code::FIELD); | 225 name, stub_holder, Code::LOAD_IC, Code::FIELD); |
| 216 if (!stub.is_null()) return stub; | 226 if (!stub.is_null()) return stub; |
| 217 | 227 |
| 218 LoadStubCompiler compiler(isolate_); | 228 LoadStubCompiler compiler(isolate_); |
| 219 Handle<Code> handler = | 229 Handle<Code> handler = |
| 220 compiler.CompileLoadField(receiver, holder, name, field); | 230 compiler.CompileLoadField(receiver, holder, name, field); |
| 221 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 231 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
| 222 return handler; | 232 return handler; |
| 223 } | 233 } |
| 224 | 234 |
| 225 | 235 |
| 226 Handle<Code> StubCache::ComputeLoadCallback( | 236 Handle<Code> StubCache::ComputeLoadCallback( |
| 227 Handle<Name> name, | 237 Handle<Name> name, |
| 228 Handle<JSObject> receiver, | 238 Handle<JSObject> receiver, |
| 229 Handle<JSObject> holder, | 239 Handle<JSObject> holder, |
| 230 Handle<ExecutableAccessorInfo> callback) { | 240 Handle<ExecutableAccessorInfo> callback) { |
| 231 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); | 241 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); |
| 232 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 242 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
| 233 Handle<Code> stub = FindHandler( | 243 Handle<Code> stub = FindStub( |
| 234 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); | 244 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); |
| 235 if (!stub.is_null()) return stub; | 245 if (!stub.is_null()) return stub; |
| 236 | 246 |
| 237 LoadStubCompiler compiler(isolate_); | 247 LoadStubCompiler compiler(isolate_); |
| 238 Handle<Code> handler = | 248 Handle<Code> handler = |
| 239 compiler.CompileLoadCallback(receiver, holder, name, callback); | 249 compiler.CompileLoadCallback(receiver, holder, name, callback); |
| 240 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 250 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
| 241 return handler; | 251 return handler; |
| 242 } | 252 } |
| 243 | 253 |
| 244 | 254 |
| 245 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name, | 255 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name, |
| 246 Handle<JSObject> receiver, | 256 Handle<JSObject> receiver, |
| 247 Handle<JSObject> holder, | 257 Handle<JSObject> holder, |
| 248 Handle<JSFunction> getter) { | 258 Handle<JSFunction> getter) { |
| 249 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 259 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
| 250 Handle<Code> stub = FindHandler( | 260 Handle<Code> stub = FindStub( |
| 251 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); | 261 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); |
| 252 if (!stub.is_null()) return stub; | 262 if (!stub.is_null()) return stub; |
| 253 | 263 |
| 254 LoadStubCompiler compiler(isolate_); | 264 LoadStubCompiler compiler(isolate_); |
| 255 Handle<Code> handler = | 265 Handle<Code> handler = |
| 256 compiler.CompileLoadViaGetter(receiver, holder, name, getter); | 266 compiler.CompileLoadViaGetter(receiver, holder, name, getter); |
| 257 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 267 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
| 258 return handler; | 268 return handler; |
| 259 } | 269 } |
| 260 | 270 |
| 261 | 271 |
| 262 Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name, | 272 Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name, |
| 263 Handle<JSObject> receiver, | 273 Handle<JSObject> receiver, |
| 264 Handle<JSObject> holder, | 274 Handle<JSObject> holder, |
| 265 Handle<JSFunction> value) { | 275 Handle<JSFunction> value) { |
| 266 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 276 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
| 267 Handle<Code> handler = FindHandler( | 277 Handle<Code> handler = FindStub( |
| 268 name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION); | 278 name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION); |
| 269 if (!handler.is_null()) return handler; | 279 if (!handler.is_null()) return handler; |
| 270 | 280 |
| 271 LoadStubCompiler compiler(isolate_); | 281 LoadStubCompiler compiler(isolate_); |
| 272 handler = compiler.CompileLoadConstant(receiver, holder, name, value); | 282 handler = compiler.CompileLoadConstant(receiver, holder, name, value); |
| 273 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 283 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
| 274 | 284 |
| 275 return handler; | 285 return handler; |
| 276 } | 286 } |
| 277 | 287 |
| 278 | 288 |
| 279 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name, | 289 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name, |
| 280 Handle<JSObject> receiver, | 290 Handle<JSObject> receiver, |
| 281 Handle<JSObject> holder) { | 291 Handle<JSObject> holder) { |
| 282 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 292 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
| 283 Handle<Code> stub = FindHandler( | 293 Handle<Code> stub = FindStub( |
| 284 name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR); | 294 name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR); |
| 285 if (!stub.is_null()) return stub; | 295 if (!stub.is_null()) return stub; |
| 286 | 296 |
| 287 LoadStubCompiler compiler(isolate_); | 297 LoadStubCompiler compiler(isolate_); |
| 288 Handle<Code> handler = | 298 Handle<Code> handler = |
| 289 compiler.CompileLoadInterceptor(receiver, holder, name); | 299 compiler.CompileLoadInterceptor(receiver, holder, name); |
| 290 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 300 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
| 291 return handler; | 301 return handler; |
| 292 } | 302 } |
| 293 | 303 |
| 294 | 304 |
| 295 Handle<Code> StubCache::ComputeLoadNormal(Handle<Name> name, | 305 Handle<Code> StubCache::ComputeLoadNormal(Handle<Name> name, |
| 296 Handle<JSObject> receiver) { | 306 Handle<JSObject> receiver) { |
| 297 return isolate_->builtins()->LoadIC_Normal(); | 307 return isolate_->builtins()->LoadIC_Normal(); |
| 298 } | 308 } |
| 299 | 309 |
| 300 | 310 |
| 301 Handle<Code> StubCache::ComputeLoadGlobal(Handle<Name> name, | 311 Handle<Code> StubCache::ComputeLoadGlobal(Handle<Name> name, |
| 302 Handle<JSObject> receiver, | 312 Handle<JSObject> receiver, |
| 303 Handle<GlobalObject> holder, | 313 Handle<GlobalObject> holder, |
| 304 Handle<JSGlobalPropertyCell> cell, | 314 Handle<JSGlobalPropertyCell> cell, |
| 305 bool is_dont_delete) { | 315 bool is_dont_delete) { |
| 306 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 316 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
| 307 Handle<Code> stub = FindStub( | 317 Handle<Code> stub = FindIC(name, stub_holder, Code::LOAD_IC, Code::NORMAL); |
| 308 name, stub_holder, Code::LOAD_IC, Code::NORMAL, Code::IC_FRAGMENT); | |
| 309 if (!stub.is_null()) return stub; | 318 if (!stub.is_null()) return stub; |
| 310 | 319 |
| 311 LoadStubCompiler compiler(isolate_); | 320 LoadStubCompiler compiler(isolate_); |
| 312 Handle<Code> ic = | 321 Handle<Code> ic = |
| 313 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); | 322 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); |
| 314 JSObject::UpdateMapCodeCache(stub_holder, name, ic); | 323 JSObject::UpdateMapCodeCache(stub_holder, name, ic); |
| 315 return ic; | 324 return ic; |
| 316 } | 325 } |
| 317 | 326 |
| 318 | 327 |
| 319 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name, | 328 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name, |
| 320 Handle<JSObject> receiver, | 329 Handle<JSObject> receiver, |
| 321 Handle<JSObject> holder, | 330 Handle<JSObject> holder, |
| 322 PropertyIndex field) { | 331 PropertyIndex field) { |
| 323 if (receiver.is_identical_to(holder)) { | 332 if (receiver.is_identical_to(holder)) { |
| 324 LoadFieldStub stub(KeyedLoadStubCompiler::receiver(), | 333 LoadFieldStub stub(KeyedLoadStubCompiler::receiver(), |
| 325 field.is_inobject(holder), | 334 field.is_inobject(holder), |
| 326 field.translate(holder)); | 335 field.translate(holder)); |
| 327 return stub.GetCode(isolate()); | 336 return stub.GetCode(isolate()); |
| 328 } | 337 } |
| 329 | 338 |
| 330 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 339 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
| 331 Handle<Code> stub = FindHandler( | 340 Handle<Code> stub = FindStub( |
| 332 name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD); | 341 name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD); |
| 333 if (!stub.is_null()) return stub; | 342 if (!stub.is_null()) return stub; |
| 334 | 343 |
| 335 KeyedLoadStubCompiler compiler(isolate_); | 344 KeyedLoadStubCompiler compiler(isolate_); |
| 336 Handle<Code> handler = | 345 Handle<Code> handler = |
| 337 compiler.CompileLoadField(receiver, holder, name, field); | 346 compiler.CompileLoadField(receiver, holder, name, field); |
| 338 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 347 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
| 339 return handler; | 348 return handler; |
| 340 } | 349 } |
| 341 | 350 |
| 342 | 351 |
| 343 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name, | 352 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name, |
| 344 Handle<JSObject> receiver, | 353 Handle<JSObject> receiver, |
| 345 Handle<JSObject> holder, | 354 Handle<JSObject> holder, |
| 346 Handle<JSFunction> value) { | 355 Handle<JSFunction> value) { |
| 347 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 356 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
| 348 Handle<Code> handler = FindHandler( | 357 Handle<Code> handler = FindStub( |
| 349 name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION); | 358 name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION); |
| 350 if (!handler.is_null()) return handler; | 359 if (!handler.is_null()) return handler; |
| 351 | 360 |
| 352 KeyedLoadStubCompiler compiler(isolate_); | 361 KeyedLoadStubCompiler compiler(isolate_); |
| 353 handler = compiler.CompileLoadConstant(receiver, holder, name, value); | 362 handler = compiler.CompileLoadConstant(receiver, holder, name, value); |
| 354 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 363 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
| 355 return handler; | 364 return handler; |
| 356 } | 365 } |
| 357 | 366 |
| 358 | 367 |
| 359 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name, | 368 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name, |
| 360 Handle<JSObject> receiver, | 369 Handle<JSObject> receiver, |
| 361 Handle<JSObject> holder) { | 370 Handle<JSObject> holder) { |
| 362 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 371 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
| 363 Handle<Code> stub = FindHandler( | 372 Handle<Code> stub = FindStub( |
| 364 name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR); | 373 name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR); |
| 365 if (!stub.is_null()) return stub; | 374 if (!stub.is_null()) return stub; |
| 366 | 375 |
| 367 KeyedLoadStubCompiler compiler(isolate_); | 376 KeyedLoadStubCompiler compiler(isolate_); |
| 368 Handle<Code> handler = | 377 Handle<Code> handler = |
| 369 compiler.CompileLoadInterceptor(receiver, holder, name); | 378 compiler.CompileLoadInterceptor(receiver, holder, name); |
| 370 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 379 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
| 371 return handler; | 380 return handler; |
| 372 } | 381 } |
| 373 | 382 |
| 374 | 383 |
| 375 Handle<Code> StubCache::ComputeKeyedLoadCallback( | 384 Handle<Code> StubCache::ComputeKeyedLoadCallback( |
| 376 Handle<Name> name, | 385 Handle<Name> name, |
| 377 Handle<JSObject> receiver, | 386 Handle<JSObject> receiver, |
| 378 Handle<JSObject> holder, | 387 Handle<JSObject> holder, |
| 379 Handle<ExecutableAccessorInfo> callback) { | 388 Handle<ExecutableAccessorInfo> callback) { |
| 380 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 389 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
| 381 Handle<Code> stub = FindHandler( | 390 Handle<Code> stub = FindStub( |
| 382 name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS); | 391 name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS); |
| 383 if (!stub.is_null()) return stub; | 392 if (!stub.is_null()) return stub; |
| 384 | 393 |
| 385 KeyedLoadStubCompiler compiler(isolate_); | 394 KeyedLoadStubCompiler compiler(isolate_); |
| 386 Handle<Code> handler = | 395 Handle<Code> handler = |
| 387 compiler.CompileLoadCallback(receiver, holder, name, callback); | 396 compiler.CompileLoadCallback(receiver, holder, name, callback); |
| 388 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 397 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
| 389 return handler; | 398 return handler; |
| 390 } | 399 } |
| 391 | 400 |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 888 | 897 |
| 889 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); | 898 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); |
| 890 return code; | 899 return code; |
| 891 } | 900 } |
| 892 | 901 |
| 893 | 902 |
| 894 Handle<Code> StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps, | 903 Handle<Code> StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps, |
| 895 CodeHandleList* handlers, | 904 CodeHandleList* handlers, |
| 896 Handle<Name> name) { | 905 Handle<Name> name) { |
| 897 LoadStubCompiler ic_compiler(isolate_); | 906 LoadStubCompiler ic_compiler(isolate_); |
| 907 Code::StubType type = handlers->length() == 1 ? handlers->at(0)->type() |
| 908 : Code::NORMAL; |
| 898 Handle<Code> ic = ic_compiler.CompilePolymorphicIC( | 909 Handle<Code> ic = ic_compiler.CompilePolymorphicIC( |
| 899 receiver_maps, handlers, name, Code::NORMAL, PROPERTY); | 910 receiver_maps, handlers, name, type, PROPERTY); |
| 900 return ic; | 911 return ic; |
| 901 } | 912 } |
| 902 | 913 |
| 903 | 914 |
| 904 Handle<Code> StubCache::ComputeStoreElementPolymorphic( | 915 Handle<Code> StubCache::ComputeStoreElementPolymorphic( |
| 905 MapHandleList* receiver_maps, | 916 MapHandleList* receiver_maps, |
| 906 KeyedAccessGrowMode grow_mode, | 917 KeyedAccessGrowMode grow_mode, |
| 907 StrictModeFlag strict_mode) { | 918 StrictModeFlag strict_mode) { |
| 908 Handle<PolymorphicCodeCache> cache = | 919 Handle<PolymorphicCodeCache> cache = |
| 909 isolate_->factory()->polymorphic_code_cache(); | 920 isolate_->factory()->polymorphic_code_cache(); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 974 } | 985 } |
| 975 | 986 |
| 976 | 987 |
| 977 void StubCache::CollectMatchingMaps(SmallMapList* types, | 988 void StubCache::CollectMatchingMaps(SmallMapList* types, |
| 978 Name* name, | 989 Name* name, |
| 979 Code::Flags flags, | 990 Code::Flags flags, |
| 980 Handle<Context> native_context, | 991 Handle<Context> native_context, |
| 981 Zone* zone) { | 992 Zone* zone) { |
| 982 for (int i = 0; i < kPrimaryTableSize; i++) { | 993 for (int i = 0; i < kPrimaryTableSize; i++) { |
| 983 if (primary_[i].key == name) { | 994 if (primary_[i].key == name) { |
| 984 Map* map = primary_[i].value->FindFirstMap(); | 995 Map* map = primary_[i].map; |
| 985 // Map can be NULL, if the stub is constant function call | 996 // Map can be NULL, if the stub is constant function call |
| 986 // with a primitive receiver. | 997 // with a primitive receiver. |
| 987 if (map == NULL) continue; | 998 if (map == NULL) continue; |
| 988 | 999 |
| 989 int offset = PrimaryOffset(name, flags, map); | 1000 int offset = PrimaryOffset(name, flags, map); |
| 990 if (entry(primary_, offset) == &primary_[i] && | 1001 if (entry(primary_, offset) == &primary_[i] && |
| 991 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) { | 1002 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) { |
| 992 types->Add(Handle<Map>(map), zone); | 1003 types->Add(Handle<Map>(map), zone); |
| 993 } | 1004 } |
| 994 } | 1005 } |
| 995 } | 1006 } |
| 996 | 1007 |
| 997 for (int i = 0; i < kSecondaryTableSize; i++) { | 1008 for (int i = 0; i < kSecondaryTableSize; i++) { |
| 998 if (secondary_[i].key == name) { | 1009 if (secondary_[i].key == name) { |
| 999 Map* map = secondary_[i].value->FindFirstMap(); | 1010 Map* map = secondary_[i].map; |
| 1000 // Map can be NULL, if the stub is constant function call | 1011 // Map can be NULL, if the stub is constant function call |
| 1001 // with a primitive receiver. | 1012 // with a primitive receiver. |
| 1002 if (map == NULL) continue; | 1013 if (map == NULL) continue; |
| 1003 | 1014 |
| 1004 // Lookup in primary table and skip duplicates. | 1015 // Lookup in primary table and skip duplicates. |
| 1005 int primary_offset = PrimaryOffset(name, flags, map); | 1016 int primary_offset = PrimaryOffset(name, flags, map); |
| 1006 Entry* primary_entry = entry(primary_, primary_offset); | 1017 Entry* primary_entry = entry(primary_, primary_offset); |
| 1007 if (primary_entry->key == name) { | 1018 if (primary_entry->key == name) { |
| 1008 Map* primary_map = primary_entry->value->FindFirstMap(); | 1019 Map* primary_map = primary_entry->map; |
| 1009 if (map == primary_map) continue; | 1020 if (map == primary_map) continue; |
| 1010 } | 1021 } |
| 1011 | 1022 |
| 1012 // Lookup in secondary table and add matches. | 1023 // Lookup in secondary table and add matches. |
| 1013 int offset = SecondaryOffset(name, flags, primary_offset); | 1024 int offset = SecondaryOffset(name, flags, primary_offset); |
| 1014 if (entry(secondary_, offset) == &secondary_[i] && | 1025 if (entry(secondary_, offset) == &secondary_[i] && |
| 1015 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) { | 1026 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) { |
| 1016 types->Add(Handle<Map>(map), zone); | 1027 types->Add(Handle<Map>(map), zone); |
| 1017 } | 1028 } |
| 1018 } | 1029 } |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1441 | 1452 |
| 1442 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); | 1453 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); |
| 1443 | 1454 |
| 1444 LoadFieldStub stub(reg, field.is_inobject(holder), field.translate(holder)); | 1455 LoadFieldStub stub(reg, field.is_inobject(holder), field.translate(holder)); |
| 1445 GenerateTailCall(stub.GetCode(isolate())); | 1456 GenerateTailCall(stub.GetCode(isolate())); |
| 1446 | 1457 |
| 1447 __ bind(&miss); | 1458 __ bind(&miss); |
| 1448 GenerateLoadMiss(masm(), kind()); | 1459 GenerateLoadMiss(masm(), kind()); |
| 1449 | 1460 |
| 1450 // Return the generated code. | 1461 // Return the generated code. |
| 1451 return GetCode(Code::HANDLER_FRAGMENT, Code::FIELD, name); | 1462 return GetCode(kind(), Code::FIELD, name); |
| 1452 } | 1463 } |
| 1453 | 1464 |
| 1454 | 1465 |
| 1455 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant( | 1466 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant( |
| 1456 Handle<JSObject> object, | 1467 Handle<JSObject> object, |
| 1457 Handle<JSObject> holder, | 1468 Handle<JSObject> holder, |
| 1458 Handle<Name> name, | 1469 Handle<Name> name, |
| 1459 Handle<JSFunction> value) { | 1470 Handle<JSFunction> value) { |
| 1460 Label success; | 1471 Label success; |
| 1461 HandlerFrontend(object, receiver(), holder, name, &success); | 1472 HandlerFrontend(object, receiver(), holder, name, &success); |
| 1462 __ bind(&success); | 1473 __ bind(&success); |
| 1463 GenerateLoadConstant(value); | 1474 GenerateLoadConstant(value); |
| 1464 | 1475 |
| 1465 // Return the generated code. | 1476 // Return the generated code. |
| 1466 return GetCode(Code::HANDLER_FRAGMENT, Code::CONSTANT_FUNCTION, name); | 1477 return GetCode(kind(), Code::CONSTANT_FUNCTION, name); |
| 1467 } | 1478 } |
| 1468 | 1479 |
| 1469 | 1480 |
| 1470 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback( | 1481 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback( |
| 1471 Handle<JSObject> object, | 1482 Handle<JSObject> object, |
| 1472 Handle<JSObject> holder, | 1483 Handle<JSObject> holder, |
| 1473 Handle<Name> name, | 1484 Handle<Name> name, |
| 1474 Handle<ExecutableAccessorInfo> callback) { | 1485 Handle<ExecutableAccessorInfo> callback) { |
| 1475 Label success; | 1486 Label success; |
| 1476 | 1487 |
| 1477 Register reg = CallbackHandlerFrontend( | 1488 Register reg = CallbackHandlerFrontend( |
| 1478 object, receiver(), holder, name, &success, callback); | 1489 object, receiver(), holder, name, &success, callback); |
| 1479 __ bind(&success); | 1490 __ bind(&success); |
| 1480 GenerateLoadCallback(reg, callback); | 1491 GenerateLoadCallback(reg, callback); |
| 1481 | 1492 |
| 1482 // Return the generated code. | 1493 // Return the generated code. |
| 1483 return GetCode(Code::HANDLER_FRAGMENT, Code::CALLBACKS, name); | 1494 return GetCode(kind(), Code::CALLBACKS, name); |
| 1484 } | 1495 } |
| 1485 | 1496 |
| 1486 | 1497 |
| 1487 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor( | 1498 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor( |
| 1488 Handle<JSObject> object, | 1499 Handle<JSObject> object, |
| 1489 Handle<JSObject> holder, | 1500 Handle<JSObject> holder, |
| 1490 Handle<Name> name) { | 1501 Handle<Name> name) { |
| 1491 Label success; | 1502 Label success; |
| 1492 | 1503 |
| 1493 LookupResult lookup(isolate()); | 1504 LookupResult lookup(isolate()); |
| 1494 LookupPostInterceptor(holder, name, &lookup); | 1505 LookupPostInterceptor(holder, name, &lookup); |
| 1495 | 1506 |
| 1496 Register reg = HandlerFrontend(object, receiver(), holder, name, &success); | 1507 Register reg = HandlerFrontend(object, receiver(), holder, name, &success); |
| 1497 __ bind(&success); | 1508 __ bind(&success); |
| 1498 // TODO(368): Compile in the whole chain: all the interceptors in | 1509 // TODO(368): Compile in the whole chain: all the interceptors in |
| 1499 // prototypes and ultimate answer. | 1510 // prototypes and ultimate answer. |
| 1500 GenerateLoadInterceptor(reg, object, holder, &lookup, name); | 1511 GenerateLoadInterceptor(reg, object, holder, &lookup, name); |
| 1501 | 1512 |
| 1502 // Return the generated code. | 1513 // Return the generated code. |
| 1503 return GetCode(Code::HANDLER_FRAGMENT, Code::INTERCEPTOR, name); | 1514 return GetCode(kind(), Code::INTERCEPTOR, name); |
| 1504 } | 1515 } |
| 1505 | 1516 |
| 1506 | 1517 |
| 1507 void BaseLoadStubCompiler::GenerateLoadPostInterceptor( | 1518 void BaseLoadStubCompiler::GenerateLoadPostInterceptor( |
| 1508 Register interceptor_reg, | 1519 Register interceptor_reg, |
| 1509 Handle<JSObject> interceptor_holder, | 1520 Handle<JSObject> interceptor_holder, |
| 1510 Handle<Name> name, | 1521 Handle<Name> name, |
| 1511 LookupResult* lookup) { | 1522 LookupResult* lookup) { |
| 1512 Label success; | 1523 Label success; |
| 1513 Handle<JSObject> holder(lookup->holder()); | 1524 Handle<JSObject> holder(lookup->holder()); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1560 Handle<JSObject> holder, | 1571 Handle<JSObject> holder, |
| 1561 Handle<Name> name, | 1572 Handle<Name> name, |
| 1562 Handle<JSFunction> getter) { | 1573 Handle<JSFunction> getter) { |
| 1563 Label success; | 1574 Label success; |
| 1564 HandlerFrontend(object, receiver(), holder, name, &success); | 1575 HandlerFrontend(object, receiver(), holder, name, &success); |
| 1565 | 1576 |
| 1566 __ bind(&success); | 1577 __ bind(&success); |
| 1567 GenerateLoadViaGetter(masm(), getter); | 1578 GenerateLoadViaGetter(masm(), getter); |
| 1568 | 1579 |
| 1569 // Return the generated code. | 1580 // Return the generated code. |
| 1570 return GetCode(Code::HANDLER_FRAGMENT, Code::CALLBACKS, name); | 1581 return GetCode(kind(), Code::CALLBACKS, name); |
| 1571 } | 1582 } |
| 1572 | 1583 |
| 1573 | 1584 |
| 1574 #undef __ | 1585 #undef __ |
| 1575 | 1586 |
| 1576 | 1587 |
| 1577 void LoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { | 1588 void LoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { |
| 1578 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 1589 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
| 1579 } | 1590 } |
| 1580 | 1591 |
| 1581 | 1592 |
| 1582 void KeyedLoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { | 1593 void KeyedLoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { |
| 1583 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); | 1594 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
| 1584 } | 1595 } |
| 1585 | 1596 |
| 1586 | 1597 |
| 1587 Handle<Code> BaseLoadStubCompiler::GetCode(Code::IcFragment fragment, | 1598 Handle<Code> BaseLoadStubCompiler::GetICCode(Code::Kind kind, |
| 1588 Code::StubType type, | 1599 Code::StubType type, |
| 1589 Handle<Name> name, | 1600 Handle<Name> name, |
| 1590 InlineCacheState state) { | 1601 InlineCacheState state) { |
| 1591 Code::Flags flags = Code::ComputeFlags(kind(), state, fragment, type); | 1602 Code::Flags flags = Code::ComputeFlags( |
| 1603 kind, state, Code::kNoExtraICState, type); |
| 1592 Handle<Code> code = GetCodeWithFlags(flags, name); | 1604 Handle<Code> code = GetCodeWithFlags(flags, name); |
| 1593 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); | 1605 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); |
| 1594 JitEvent(name, code); | 1606 JitEvent(name, code); |
| 1607 return code; |
| 1608 } |
| 1609 |
| 1610 |
| 1611 Handle<Code> BaseLoadStubCompiler::GetCode(Code::Kind kind, |
| 1612 Code::StubType type, |
| 1613 Handle<Name> name) { |
| 1614 ASSERT(type != Code::NORMAL); |
| 1615 Code::Flags flags = Code::ComputeFlags( |
| 1616 Code::STUB, MONOMORPHIC, Code::kNoExtraICState, type, kind); |
| 1617 Handle<Code> code = GetCodeWithFlags(flags, name); |
| 1618 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); |
| 1619 JitEvent(name, code); |
| 1595 return code; | 1620 return code; |
| 1596 } | 1621 } |
| 1597 | 1622 |
| 1598 | 1623 |
| 1599 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps, | 1624 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps, |
| 1600 CodeHandleList* handlers) { | 1625 CodeHandleList* handlers) { |
| 1601 for (int i = 0; i < receiver_maps->length(); ++i) { | 1626 for (int i = 0; i < receiver_maps->length(); ++i) { |
| 1602 Handle<Map> receiver_map = receiver_maps->at(i); | 1627 Handle<Map> receiver_map = receiver_maps->at(i); |
| 1603 Handle<Code> cached_stub; | 1628 Handle<Code> cached_stub; |
| 1604 | 1629 |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1853 Handle<FunctionTemplateInfo>( | 1878 Handle<FunctionTemplateInfo>( |
| 1854 FunctionTemplateInfo::cast(signature->receiver())); | 1879 FunctionTemplateInfo::cast(signature->receiver())); |
| 1855 } | 1880 } |
| 1856 } | 1881 } |
| 1857 | 1882 |
| 1858 is_simple_api_call_ = true; | 1883 is_simple_api_call_ = true; |
| 1859 } | 1884 } |
| 1860 | 1885 |
| 1861 | 1886 |
| 1862 } } // namespace v8::internal | 1887 } } // namespace v8::internal |
| OLD | NEW |