Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: src/type-info.cc

Issue 16361015: Migrate Compare ICs to new type rep (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comments Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/type-info.h ('k') | src/types.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 24 matching lines...) Expand all
35 #include "stub-cache.h" 35 #include "stub-cache.h"
36 #include "type-info.h" 36 #include "type-info.h"
37 37
38 #include "ic-inl.h" 38 #include "ic-inl.h"
39 #include "objects-inl.h" 39 #include "objects-inl.h"
40 40
41 namespace v8 { 41 namespace v8 {
42 namespace internal { 42 namespace internal {
43 43
44 44
45 TypeInfo TypeInfo::TypeFromValue(Handle<Object> value) { 45 TypeInfo TypeInfo::FromValue(Handle<Object> value) {
46 TypeInfo info;
47 if (value->IsSmi()) { 46 if (value->IsSmi()) {
48 info = TypeInfo::Smi(); 47 return TypeInfo::Smi();
49 } else if (value->IsHeapNumber()) { 48 } else if (value->IsHeapNumber()) {
50 info = TypeInfo::IsInt32Double(HeapNumber::cast(*value)->value()) 49 return TypeInfo::IsInt32Double(HeapNumber::cast(*value)->value())
51 ? TypeInfo::Integer32() 50 ? TypeInfo::Integer32()
52 : TypeInfo::Double(); 51 : TypeInfo::Double();
53 } else if (value->IsString()) { 52 } else if (value->IsString()) {
54 info = TypeInfo::String(); 53 return TypeInfo::String();
55 } else {
56 info = TypeInfo::Unknown();
57 } 54 }
58 return info; 55 return TypeInfo::Unknown();
59 } 56 }
60 57
61 58
62 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code, 59 TypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code,
63 Handle<Context> native_context, 60 Handle<Context> native_context,
64 Isolate* isolate, 61 Isolate* isolate,
65 Zone* zone) 62 Zone* zone)
66 : native_context_(native_context), 63 : native_context_(native_context),
67 isolate_(isolate), 64 isolate_(isolate),
68 zone_(zone) { 65 zone_(zone) {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 Handle<Code> code = Handle<Code>::cast(map_or_code); 224 Handle<Code> code = Handle<Code>::cast(map_or_code);
228 Map* map = code->FindFirstMap()->CurrentMapForDeprecated(); 225 Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
229 return map == NULL || CanRetainOtherContext(map, *native_context_) 226 return map == NULL || CanRetainOtherContext(map, *native_context_)
230 ? Handle<Map>::null() 227 ? Handle<Map>::null()
231 : Handle<Map>(map); 228 : Handle<Map>(map);
232 } 229 }
233 return Handle<Map>::cast(map_or_code); 230 return Handle<Map>::cast(map_or_code);
234 } 231 }
235 232
236 233
237 Handle<Map> TypeFeedbackOracle::CompareNilMonomorphicReceiverType(
238 CompareOperation* expr) {
239 Handle<Object> maybe_code = GetInfo(expr->CompareOperationFeedbackId());
240 if (maybe_code->IsCode()) {
241 Map* map = Handle<Code>::cast(maybe_code)->FindFirstMap();
242 if (map == NULL) return Handle<Map>();
243 map = map->CurrentMapForDeprecated();
244 return map == NULL || CanRetainOtherContext(map, *native_context_)
245 ? Handle<Map>()
246 : Handle<Map>(map);
247 } else if (maybe_code->IsMap()) {
248 ASSERT(!Handle<Map>::cast(maybe_code)->is_deprecated());
249 return Handle<Map>::cast(maybe_code);
250 }
251 return Handle<Map>();
252 }
253
254
255 KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode( 234 KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode(
256 TypeFeedbackId ast_id) { 235 TypeFeedbackId ast_id) {
257 Handle<Object> map_or_code = GetInfo(ast_id); 236 Handle<Object> map_or_code = GetInfo(ast_id);
258 if (map_or_code->IsCode()) { 237 if (map_or_code->IsCode()) {
259 Handle<Code> code = Handle<Code>::cast(map_or_code); 238 Handle<Code> code = Handle<Code>::cast(map_or_code);
260 if (code->kind() == Code::KEYED_STORE_IC) { 239 if (code->kind() == Code::KEYED_STORE_IC) {
261 return Code::GetKeyedAccessStoreMode(code->extra_ic_state()); 240 return Code::GetKeyedAccessStoreMode(code->extra_ic_state());
262 } 241 }
263 } 242 }
264 return STANDARD_STORE; 243 return STANDARD_STORE;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 bool TypeFeedbackOracle::LoadIsStub(Property* expr, ICStub* stub) { 334 bool TypeFeedbackOracle::LoadIsStub(Property* expr, ICStub* stub) {
356 Handle<Object> object = GetInfo(expr->PropertyFeedbackId()); 335 Handle<Object> object = GetInfo(expr->PropertyFeedbackId());
357 if (!object->IsCode()) return false; 336 if (!object->IsCode()) return false;
358 Handle<Code> code = Handle<Code>::cast(object); 337 Handle<Code> code = Handle<Code>::cast(object);
359 if (!code->is_load_stub()) return false; 338 if (!code->is_load_stub()) return false;
360 if (code->ic_state() != MONOMORPHIC) return false; 339 if (code->ic_state() != MONOMORPHIC) return false;
361 return stub->Describes(*code); 340 return stub->Describes(*code);
362 } 341 }
363 342
364 343
365 static TypeInfo TypeFromCompareType(CompareIC::State state) { 344 void TypeFeedbackOracle::CompareTypes(TypeFeedbackId id,
366 switch (state) { 345 Handle<Type>* left_type,
367 case CompareIC::UNINITIALIZED: 346 Handle<Type>* right_type,
368 // Uninitialized means never executed. 347 Handle<Type>* overall_type,
369 return TypeInfo::Uninitialized(); 348 Handle<Type>* compare_nil_type) {
370 case CompareIC::SMI: 349 *left_type = *right_type = *overall_type = *compare_nil_type =
371 return TypeInfo::Smi(); 350 handle(Type::Any(), isolate_);
372 case CompareIC::NUMBER: 351 Handle<Object> info = GetInfo(id);
373 return TypeInfo::Number(); 352 if (!info->IsCode()) return;
374 case CompareIC::INTERNALIZED_STRING: 353 Handle<Code> code = Handle<Code>::cast(info);
375 return TypeInfo::InternalizedString(); 354
376 case CompareIC::STRING: 355 Handle<Map> map;
377 return TypeInfo::String(); 356 Map* raw_map = code->FindFirstMap();
378 case CompareIC::OBJECT: 357 if (raw_map != NULL) {
379 case CompareIC::KNOWN_OBJECT: 358 raw_map = raw_map->CurrentMapForDeprecated();
380 // TODO(kasperl): We really need a type for JS objects here. 359 if (!CanRetainOtherContext(raw_map, *native_context_)) {
381 return TypeInfo::NonPrimitive(); 360 map = handle(raw_map, isolate_);
382 case CompareIC::GENERIC: 361 }
383 default: 362 }
384 return TypeInfo::Unknown(); 363
364 if (code->is_compare_ic_stub()) {
365 int stub_minor_key = code->stub_info();
366 CompareIC::State left_state, right_state, handler_state;
367 ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state,
368 &handler_state, NULL);
369 *left_type = CompareIC::StateToType(isolate_, left_state);
370 *right_type = CompareIC::StateToType(isolate_, right_state);
371 *overall_type = CompareIC::StateToType(isolate_, handler_state, map);
372 } else if (code->is_compare_nil_ic_stub()) {
373 CompareNilICStub::State state(code->compare_nil_state());
374 *compare_nil_type = CompareNilICStub::StateToType(isolate_, state, map);
385 } 375 }
386 } 376 }
387 377
388 378
389 void TypeFeedbackOracle::CompareType(CompareOperation* expr,
390 TypeInfo* left_type,
391 TypeInfo* right_type,
392 TypeInfo* overall_type) {
393 Handle<Object> object = GetInfo(expr->CompareOperationFeedbackId());
394 TypeInfo unknown = TypeInfo::Unknown();
395 if (!object->IsCode()) {
396 *left_type = *right_type = *overall_type = unknown;
397 return;
398 }
399 Handle<Code> code = Handle<Code>::cast(object);
400 if (!code->is_compare_ic_stub()) {
401 *left_type = *right_type = *overall_type = unknown;
402 return;
403 }
404
405 int stub_minor_key = code->stub_info();
406 CompareIC::State left_state, right_state, handler_state;
407 ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state,
408 &handler_state, NULL);
409 *left_type = TypeFromCompareType(left_state);
410 *right_type = TypeFromCompareType(right_state);
411 *overall_type = TypeFromCompareType(handler_state);
412 }
413
414
415 Handle<Map> TypeFeedbackOracle::GetCompareMap(CompareOperation* expr) {
416 Handle<Object> object = GetInfo(expr->CompareOperationFeedbackId());
417 if (!object->IsCode()) return Handle<Map>::null();
418 Handle<Code> code = Handle<Code>::cast(object);
419 if (!code->is_compare_ic_stub()) return Handle<Map>::null();
420 CompareIC::State state = ICCompareStub::CompareState(code->stub_info());
421 if (state != CompareIC::KNOWN_OBJECT) {
422 return Handle<Map>::null();
423 }
424 Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
425 return map == NULL || CanRetainOtherContext(map, *native_context_)
426 ? Handle<Map>::null()
427 : Handle<Map>(map);
428 }
429
430
431 TypeInfo TypeFeedbackOracle::UnaryType(UnaryOperation* expr) { 379 TypeInfo TypeFeedbackOracle::UnaryType(UnaryOperation* expr) {
432 Handle<Object> object = GetInfo(expr->UnaryOperationFeedbackId()); 380 Handle<Object> object = GetInfo(expr->UnaryOperationFeedbackId());
433 TypeInfo unknown = TypeInfo::Unknown(); 381 TypeInfo unknown = TypeInfo::Unknown();
434 if (!object->IsCode()) return unknown; 382 if (!object->IsCode()) return unknown;
435 Handle<Code> code = Handle<Code>::cast(object); 383 Handle<Code> code = Handle<Code>::cast(object);
436 ASSERT(code->is_unary_op_stub()); 384 ASSERT(code->is_unary_op_stub());
437 UnaryOpIC::TypeInfo type = static_cast<UnaryOpIC::TypeInfo>( 385 UnaryOpIC::TypeInfo type = static_cast<UnaryOpIC::TypeInfo>(
438 code->unary_op_type()); 386 code->unary_op_type());
439 switch (type) { 387 switch (type) {
440 case UnaryOpIC::SMI: 388 case UnaryOpIC::SMI:
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 BinaryOpStub::decode_has_fixed_right_arg_from_minor_key(minor_key); 436 BinaryOpStub::decode_has_fixed_right_arg_from_minor_key(minor_key);
489 *fixed_right_arg_value = 437 *fixed_right_arg_value =
490 BinaryOpStub::decode_fixed_right_arg_value_from_minor_key(minor_key); 438 BinaryOpStub::decode_fixed_right_arg_value_from_minor_key(minor_key);
491 return; 439 return;
492 } 440 }
493 // Not a binary op stub. 441 // Not a binary op stub.
494 *left = *right = *result = unknown; 442 *left = *right = *result = unknown;
495 } 443 }
496 444
497 445
498 TypeInfo TypeFeedbackOracle::SwitchType(CaseClause* clause) { 446 Handle<Type> TypeFeedbackOracle::ClauseType(TypeFeedbackId id) {
499 Handle<Object> object = GetInfo(clause->CompareId()); 447 Handle<Object> info = GetInfo(id);
500 TypeInfo unknown = TypeInfo::Unknown(); 448 Handle<Type> result(Type::None(), isolate_);
501 if (!object->IsCode()) return unknown; 449 if (info->IsCode() && Handle<Code>::cast(info)->is_compare_ic_stub()) {
502 Handle<Code> code = Handle<Code>::cast(object); 450 Handle<Code> code = Handle<Code>::cast(info);
503 if (!code->is_compare_ic_stub()) return unknown; 451 CompareIC::State state = ICCompareStub::CompareState(code->stub_info());
504 452 result = CompareIC::StateToType(isolate_, state);
505 CompareIC::State state = ICCompareStub::CompareState(code->stub_info()); 453 }
506 return TypeFromCompareType(state); 454 return result;
507 } 455 }
508 456
509 457
510 TypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) { 458 TypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) {
511 Handle<Object> object = GetInfo(expr->CountBinOpFeedbackId()); 459 Handle<Object> object = GetInfo(expr->CountBinOpFeedbackId());
512 TypeInfo unknown = TypeInfo::Unknown(); 460 TypeInfo unknown = TypeInfo::Unknown();
513 if (!object->IsCode()) return unknown; 461 if (!object->IsCode()) return unknown;
514 Handle<Code> code = Handle<Code>::cast(object); 462 Handle<Code> code = Handle<Code>::cast(object);
515 if (!code->is_binary_op_stub()) return unknown; 463 if (!code->is_binary_op_stub()) return unknown;
516 464
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 } 575 }
628 } 576 }
629 577
630 578
631 byte TypeFeedbackOracle::ToBooleanTypes(TypeFeedbackId id) { 579 byte TypeFeedbackOracle::ToBooleanTypes(TypeFeedbackId id) {
632 Handle<Object> object = GetInfo(id); 580 Handle<Object> object = GetInfo(id);
633 return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0; 581 return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0;
634 } 582 }
635 583
636 584
637 byte TypeFeedbackOracle::CompareNilTypes(CompareOperation* expr) {
638 Handle<Object> object = GetInfo(expr->CompareOperationFeedbackId());
639 if (object->IsCode() &&
640 Handle<Code>::cast(object)->is_compare_nil_ic_stub()) {
641 return Handle<Code>::cast(object)->compare_nil_types();
642 } else {
643 return CompareNilICStub::Types::FullCompare().ToIntegral();
644 }
645 }
646
647
648 // Things are a bit tricky here: The iterator for the RelocInfos and the infos 585 // Things are a bit tricky here: The iterator for the RelocInfos and the infos
649 // themselves are not GC-safe, so we first get all infos, then we create the 586 // themselves are not GC-safe, so we first get all infos, then we create the
650 // dictionary (possibly triggering GC), and finally we relocate the collected 587 // dictionary (possibly triggering GC), and finally we relocate the collected
651 // infos before we process them. 588 // infos before we process them.
652 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) { 589 void TypeFeedbackOracle::BuildDictionary(Handle<Code> code) {
653 DisallowHeapAllocation no_allocation; 590 DisallowHeapAllocation no_allocation;
654 ZoneList<RelocInfo> infos(16, zone()); 591 ZoneList<RelocInfo> infos(16, zone());
655 HandleScope scope(isolate_); 592 HandleScope scope(isolate_);
656 GetRelocInfos(code, &infos); 593 GetRelocInfos(code, &infos);
657 CreateDictionary(code, &infos); 594 CreateDictionary(code, &infos);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 USE(maybe_result); 713 USE(maybe_result);
777 #ifdef DEBUG 714 #ifdef DEBUG
778 Object* result = NULL; 715 Object* result = NULL;
779 // Dictionary has been allocated with sufficient size for all elements. 716 // Dictionary has been allocated with sufficient size for all elements.
780 ASSERT(maybe_result->ToObject(&result)); 717 ASSERT(maybe_result->ToObject(&result));
781 ASSERT(*dictionary_ == result); 718 ASSERT(*dictionary_ == result);
782 #endif 719 #endif
783 } 720 }
784 721
785 } } // namespace v8::internal 722 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/type-info.h ('k') | src/types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698