OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/cpu-profiler.h" | 9 #include "src/cpu-profiler.h" |
10 #include "src/factory.h" | 10 #include "src/factory.h" |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 stub.GetCode(); | 212 stub.GetCode(); |
213 } | 213 } |
214 } | 214 } |
215 | 215 |
216 // Generate special versions of the stub. | 216 // Generate special versions of the stub. |
217 BinaryOpIC::State::GenerateAheadOfTime(isolate, &GenerateAheadOfTime); | 217 BinaryOpIC::State::GenerateAheadOfTime(isolate, &GenerateAheadOfTime); |
218 } | 218 } |
219 | 219 |
220 | 220 |
221 void BinaryOpICStub::PrintState(OStream& os) const { // NOLINT | 221 void BinaryOpICStub::PrintState(OStream& os) const { // NOLINT |
222 os << state_; | 222 os << state(); |
223 } | 223 } |
224 | 224 |
225 | 225 |
226 // static | 226 // static |
227 void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate, | 227 void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate, |
228 const BinaryOpIC::State& state) { | 228 const BinaryOpIC::State& state) { |
229 BinaryOpICStub stub(isolate, state); | 229 BinaryOpICStub stub(isolate, state); |
230 stub.GetCode(); | 230 stub.GetCode(); |
231 } | 231 } |
232 | 232 |
(...skipping 30 matching lines...) Expand all Loading... |
263 } else if ((flags() & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { | 263 } else if ((flags() & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { |
264 os << "_CheckRight"; | 264 os << "_CheckRight"; |
265 } | 265 } |
266 if (pretenure_flag() == TENURED) { | 266 if (pretenure_flag() == TENURED) { |
267 os << "_Tenured"; | 267 os << "_Tenured"; |
268 } | 268 } |
269 } | 269 } |
270 | 270 |
271 | 271 |
272 InlineCacheState ICCompareStub::GetICState() const { | 272 InlineCacheState ICCompareStub::GetICState() const { |
273 CompareIC::State state = Max(left_, right_); | 273 CompareIC::State state = Max(left(), right()); |
274 switch (state) { | 274 switch (state) { |
275 case CompareIC::UNINITIALIZED: | 275 case CompareIC::UNINITIALIZED: |
276 return ::v8::internal::UNINITIALIZED; | 276 return ::v8::internal::UNINITIALIZED; |
277 case CompareIC::SMI: | 277 case CompareIC::SMI: |
278 case CompareIC::NUMBER: | 278 case CompareIC::NUMBER: |
279 case CompareIC::INTERNALIZED_STRING: | 279 case CompareIC::INTERNALIZED_STRING: |
280 case CompareIC::STRING: | 280 case CompareIC::STRING: |
281 case CompareIC::UNIQUE_NAME: | 281 case CompareIC::UNIQUE_NAME: |
282 case CompareIC::OBJECT: | 282 case CompareIC::OBJECT: |
283 case CompareIC::KNOWN_OBJECT: | 283 case CompareIC::KNOWN_OBJECT: |
(...skipping 16 matching lines...) Expand all Loading... |
300 factory->compare_ic_string(), | 300 factory->compare_ic_string(), |
301 new_object); | 301 new_object); |
302 } | 302 } |
303 | 303 |
304 | 304 |
305 bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) { | 305 bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) { |
306 Factory* factory = isolate()->factory(); | 306 Factory* factory = isolate()->factory(); |
307 Code::Flags flags = Code::ComputeFlags( | 307 Code::Flags flags = Code::ComputeFlags( |
308 GetCodeKind(), | 308 GetCodeKind(), |
309 UNINITIALIZED); | 309 UNINITIALIZED); |
310 DCHECK(op_ == Token::EQ || op_ == Token::EQ_STRICT); | 310 DCHECK(op() == Token::EQ || op() == Token::EQ_STRICT); |
311 Handle<Object> probe( | 311 Handle<Object> probe( |
312 known_map_->FindInCodeCache( | 312 known_map_->FindInCodeCache( |
313 strict() ? | 313 strict() ? |
314 *factory->strict_compare_ic_string() : | 314 *factory->strict_compare_ic_string() : |
315 *factory->compare_ic_string(), | 315 *factory->compare_ic_string(), |
316 flags), | 316 flags), |
317 isolate()); | 317 isolate()); |
318 if (probe->IsCode()) { | 318 if (probe->IsCode()) { |
319 *code_out = Code::cast(*probe); | 319 *code_out = Code::cast(*probe); |
320 #ifdef DEBUG | 320 #ifdef DEBUG |
321 Token::Value cached_op; | 321 ICCompareStub decode((*code_out)->stub_key()); |
322 ICCompareStub::DecodeKey((*code_out)->stub_key(), NULL, NULL, NULL, | 322 DCHECK(op() == decode.op()); |
323 &cached_op); | 323 DCHECK(left() == decode.left()); |
324 DCHECK(op_ == cached_op); | 324 DCHECK(right() == decode.right()); |
| 325 DCHECK(state() == decode.state()); |
325 #endif | 326 #endif |
326 return true; | 327 return true; |
327 } | 328 } |
328 return false; | 329 return false; |
329 } | 330 } |
330 | 331 |
331 | 332 |
332 uint32_t ICCompareStub::MinorKey() const { | |
333 return OpField::encode(op_ - Token::EQ) | | |
334 LeftStateField::encode(left_) | | |
335 RightStateField::encode(right_) | | |
336 HandlerStateField::encode(state_); | |
337 } | |
338 | |
339 | |
340 void ICCompareStub::DecodeKey(uint32_t stub_key, CompareIC::State* left_state, | |
341 CompareIC::State* right_state, | |
342 CompareIC::State* handler_state, | |
343 Token::Value* op) { | |
344 int minor_key = MinorKeyFromKey(stub_key); | |
345 if (left_state) { | |
346 *left_state = | |
347 static_cast<CompareIC::State>(LeftStateField::decode(minor_key)); | |
348 } | |
349 if (right_state) { | |
350 *right_state = | |
351 static_cast<CompareIC::State>(RightStateField::decode(minor_key)); | |
352 } | |
353 if (handler_state) { | |
354 *handler_state = | |
355 static_cast<CompareIC::State>(HandlerStateField::decode(minor_key)); | |
356 } | |
357 if (op) { | |
358 *op = static_cast<Token::Value>(OpField::decode(minor_key) + Token::EQ); | |
359 } | |
360 } | |
361 | |
362 | |
363 void ICCompareStub::Generate(MacroAssembler* masm) { | 333 void ICCompareStub::Generate(MacroAssembler* masm) { |
364 switch (state_) { | 334 switch (state()) { |
365 case CompareIC::UNINITIALIZED: | 335 case CompareIC::UNINITIALIZED: |
366 GenerateMiss(masm); | 336 GenerateMiss(masm); |
367 break; | 337 break; |
368 case CompareIC::SMI: | 338 case CompareIC::SMI: |
369 GenerateSmis(masm); | 339 GenerateSmis(masm); |
370 break; | 340 break; |
371 case CompareIC::NUMBER: | 341 case CompareIC::NUMBER: |
372 GenerateNumbers(masm); | 342 GenerateNumbers(masm); |
373 break; | 343 break; |
374 case CompareIC::STRING: | 344 case CompareIC::STRING: |
(...skipping 13 matching lines...) Expand all Loading... |
388 GenerateKnownObjects(masm); | 358 GenerateKnownObjects(masm); |
389 break; | 359 break; |
390 case CompareIC::GENERIC: | 360 case CompareIC::GENERIC: |
391 GenerateGeneric(masm); | 361 GenerateGeneric(masm); |
392 break; | 362 break; |
393 } | 363 } |
394 } | 364 } |
395 | 365 |
396 | 366 |
397 void CompareNilICStub::UpdateStatus(Handle<Object> object) { | 367 void CompareNilICStub::UpdateStatus(Handle<Object> object) { |
398 DCHECK(!state_.Contains(GENERIC)); | 368 State state = this->state(); |
399 State old_state(state_); | 369 DCHECK(!state.Contains(GENERIC)); |
| 370 State old_state = state; |
400 if (object->IsNull()) { | 371 if (object->IsNull()) { |
401 state_.Add(NULL_TYPE); | 372 state.Add(NULL_TYPE); |
402 } else if (object->IsUndefined()) { | 373 } else if (object->IsUndefined()) { |
403 state_.Add(UNDEFINED); | 374 state.Add(UNDEFINED); |
404 } else if (object->IsUndetectableObject() || | 375 } else if (object->IsUndetectableObject() || |
405 object->IsOddball() || | 376 object->IsOddball() || |
406 !object->IsHeapObject()) { | 377 !object->IsHeapObject()) { |
407 state_.RemoveAll(); | 378 state.RemoveAll(); |
408 state_.Add(GENERIC); | 379 state.Add(GENERIC); |
409 } else if (IsMonomorphic()) { | 380 } else if (IsMonomorphic()) { |
410 state_.RemoveAll(); | 381 state.RemoveAll(); |
411 state_.Add(GENERIC); | 382 state.Add(GENERIC); |
412 } else { | 383 } else { |
413 state_.Add(MONOMORPHIC_MAP); | 384 state.Add(MONOMORPHIC_MAP); |
414 } | 385 } |
415 TraceTransition(old_state, state_); | 386 TraceTransition(old_state, state); |
| 387 set_sub_minor_key(TypesBits::update(sub_minor_key(), state.ToIntegral())); |
416 } | 388 } |
417 | 389 |
418 | 390 |
419 template<class StateType> | 391 template<class StateType> |
420 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) { | 392 void HydrogenCodeStub::TraceTransition(StateType from, StateType to) { |
421 // Note: Although a no-op transition is semantically OK, it is hinting at a | 393 // Note: Although a no-op transition is semantically OK, it is hinting at a |
422 // bug somewhere in our state transition machinery. | 394 // bug somewhere in our state transition machinery. |
423 DCHECK(from != to); | 395 DCHECK(from != to); |
424 if (!FLAG_trace_ic) return; | 396 if (!FLAG_trace_ic) return; |
425 OFStream os(stdout); | 397 OFStream os(stdout); |
426 os << "["; | 398 os << "["; |
427 PrintBaseName(os); | 399 PrintBaseName(os); |
428 os << ": " << from << "=>" << to << "]" << endl; | 400 os << ": " << from << "=>" << to << "]" << endl; |
429 } | 401 } |
430 | 402 |
431 | 403 |
432 void CompareNilICStub::PrintBaseName(OStream& os) const { // NOLINT | 404 void CompareNilICStub::PrintBaseName(OStream& os) const { // NOLINT |
433 CodeStub::PrintBaseName(os); | 405 CodeStub::PrintBaseName(os); |
434 os << ((nil_value_ == kNullValue) ? "(NullValue)" : "(UndefinedValue)"); | 406 os << ((nil_value() == kNullValue) ? "(NullValue)" : "(UndefinedValue)"); |
435 } | 407 } |
436 | 408 |
437 | 409 |
438 void CompareNilICStub::PrintState(OStream& os) const { // NOLINT | 410 void CompareNilICStub::PrintState(OStream& os) const { // NOLINT |
439 os << state_; | 411 os << state(); |
440 } | 412 } |
441 | 413 |
442 | 414 |
443 // TODO(svenpanne) Make this a real infix_ostream_iterator. | 415 // TODO(svenpanne) Make this a real infix_ostream_iterator. |
444 class SimpleListPrinter { | 416 class SimpleListPrinter { |
445 public: | 417 public: |
446 explicit SimpleListPrinter(OStream& os) : os_(os), first_(true) {} | 418 explicit SimpleListPrinter(OStream& os) : os_(os), first_(true) {} |
447 | 419 |
448 void Add(const char* s) { | 420 void Add(const char* s) { |
449 if (first_) { | 421 if (first_) { |
(...skipping 16 matching lines...) Expand all Loading... |
466 if (s.IsEmpty()) p.Add("None"); | 438 if (s.IsEmpty()) p.Add("None"); |
467 if (s.Contains(CompareNilICStub::UNDEFINED)) p.Add("Undefined"); | 439 if (s.Contains(CompareNilICStub::UNDEFINED)) p.Add("Undefined"); |
468 if (s.Contains(CompareNilICStub::NULL_TYPE)) p.Add("Null"); | 440 if (s.Contains(CompareNilICStub::NULL_TYPE)) p.Add("Null"); |
469 if (s.Contains(CompareNilICStub::MONOMORPHIC_MAP)) p.Add("MonomorphicMap"); | 441 if (s.Contains(CompareNilICStub::MONOMORPHIC_MAP)) p.Add("MonomorphicMap"); |
470 if (s.Contains(CompareNilICStub::GENERIC)) p.Add("Generic"); | 442 if (s.Contains(CompareNilICStub::GENERIC)) p.Add("Generic"); |
471 return os << ")"; | 443 return os << ")"; |
472 } | 444 } |
473 | 445 |
474 | 446 |
475 Type* CompareNilICStub::GetType(Zone* zone, Handle<Map> map) { | 447 Type* CompareNilICStub::GetType(Zone* zone, Handle<Map> map) { |
476 if (state_.Contains(CompareNilICStub::GENERIC)) { | 448 State state = this->state(); |
477 return Type::Any(zone); | 449 if (state.Contains(CompareNilICStub::GENERIC)) return Type::Any(zone); |
478 } | |
479 | 450 |
480 Type* result = Type::None(zone); | 451 Type* result = Type::None(zone); |
481 if (state_.Contains(CompareNilICStub::UNDEFINED)) { | 452 if (state.Contains(CompareNilICStub::UNDEFINED)) { |
482 result = Type::Union(result, Type::Undefined(zone), zone); | 453 result = Type::Union(result, Type::Undefined(zone), zone); |
483 } | 454 } |
484 if (state_.Contains(CompareNilICStub::NULL_TYPE)) { | 455 if (state.Contains(CompareNilICStub::NULL_TYPE)) { |
485 result = Type::Union(result, Type::Null(zone), zone); | 456 result = Type::Union(result, Type::Null(zone), zone); |
486 } | 457 } |
487 if (state_.Contains(CompareNilICStub::MONOMORPHIC_MAP)) { | 458 if (state.Contains(CompareNilICStub::MONOMORPHIC_MAP)) { |
488 Type* type = | 459 Type* type = |
489 map.is_null() ? Type::Detectable(zone) : Type::Class(map, zone); | 460 map.is_null() ? Type::Detectable(zone) : Type::Class(map, zone); |
490 result = Type::Union(result, type, zone); | 461 result = Type::Union(result, type, zone); |
491 } | 462 } |
492 | 463 |
493 return result; | 464 return result; |
494 } | 465 } |
495 | 466 |
496 | 467 |
497 Type* CompareNilICStub::GetInputType(Zone* zone, Handle<Map> map) { | 468 Type* CompareNilICStub::GetInputType(Zone* zone, Handle<Map> map) { |
498 Type* output_type = GetType(zone, map); | 469 Type* output_type = GetType(zone, map); |
499 Type* nil_type = | 470 Type* nil_type = |
500 nil_value_ == kNullValue ? Type::Null(zone) : Type::Undefined(zone); | 471 nil_value() == kNullValue ? Type::Null(zone) : Type::Undefined(zone); |
501 return Type::Union(output_type, nil_type, zone); | 472 return Type::Union(output_type, nil_type, zone); |
502 } | 473 } |
503 | 474 |
504 | 475 |
505 void CallIC_ArrayStub::PrintState(OStream& os) const { // NOLINT | 476 void CallIC_ArrayStub::PrintState(OStream& os) const { // NOLINT |
506 os << state() << " (Array)"; | 477 os << state() << " (Array)"; |
507 } | 478 } |
508 | 479 |
509 | 480 |
510 void CallICStub::PrintState(OStream& os) const { // NOLINT | 481 void CallICStub::PrintState(OStream& os) const { // NOLINT |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 InstallDescriptor(isolate, &stub3); | 1087 InstallDescriptor(isolate, &stub3); |
1117 } | 1088 } |
1118 | 1089 |
1119 InternalArrayConstructorStub::InternalArrayConstructorStub( | 1090 InternalArrayConstructorStub::InternalArrayConstructorStub( |
1120 Isolate* isolate) : PlatformCodeStub(isolate) { | 1091 Isolate* isolate) : PlatformCodeStub(isolate) { |
1121 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); | 1092 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); |
1122 } | 1093 } |
1123 | 1094 |
1124 | 1095 |
1125 } } // namespace v8::internal | 1096 } } // namespace v8::internal |
OLD | NEW |