OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 | 69 |
70 | 70 |
71 void TypeFeedbackOracle::Initialize(Handle<Code> code) { | 71 void TypeFeedbackOracle::Initialize(Handle<Code> code) { |
72 ASSERT(map_.is_null()); // Only initialize once. | 72 ASSERT(map_.is_null()); // Only initialize once. |
73 map_ = Factory::NewJSObject(Top::object_function()); | 73 map_ = Factory::NewJSObject(Top::object_function()); |
74 PopulateMap(code); | 74 PopulateMap(code); |
75 } | 75 } |
76 | 76 |
77 | 77 |
78 bool TypeFeedbackOracle::LoadIsMonomorphic(Property* expr) { | 78 bool TypeFeedbackOracle::LoadIsMonomorphic(Property* expr) { |
79 return GetElement(map_, expr->position())->IsMap(); | 79 Handle<Object> map_or_code(GetElement(map_, expr->position())); |
| 80 if (map_or_code->IsMap()) return true; |
| 81 if (map_or_code->IsCode()) { |
| 82 Handle<Code> code(Code::cast(*map_or_code)); |
| 83 return code->kind() == Code::KEYED_EXTERNAL_ARRAY_LOAD_IC && |
| 84 code->FindFirstMap() != NULL; |
| 85 } |
| 86 return false; |
80 } | 87 } |
81 | 88 |
82 | 89 |
83 bool TypeFeedbackOracle:: StoreIsMonomorphic(Assignment* expr) { | 90 bool TypeFeedbackOracle::StoreIsMonomorphic(Assignment* expr) { |
84 return GetElement(map_, expr->position())->IsMap(); | 91 Handle<Object> map_or_code(GetElement(map_, expr->position())); |
| 92 if (map_or_code->IsMap()) return true; |
| 93 if (map_or_code->IsCode()) { |
| 94 Handle<Code> code(Code::cast(*map_or_code)); |
| 95 return code->kind() == Code::KEYED_EXTERNAL_ARRAY_STORE_IC && |
| 96 code->FindFirstMap() != NULL; |
| 97 } |
| 98 return false; |
85 } | 99 } |
86 | 100 |
87 | 101 |
88 bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) { | 102 bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) { |
89 Handle<Object> value = GetElement(map_, expr->position()); | 103 Handle<Object> value = GetElement(map_, expr->position()); |
90 return value->IsMap() || value->IsSmi(); | 104 return value->IsMap() || value->IsSmi(); |
91 } | 105 } |
92 | 106 |
93 | 107 |
94 Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) { | 108 Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) { |
95 ASSERT(LoadIsMonomorphic(expr)); | 109 ASSERT(LoadIsMonomorphic(expr)); |
96 return Handle<Map>::cast(GetElement(map_, expr->position())); | 110 Handle<Object> map_or_code( |
| 111 Handle<HeapObject>::cast(GetElement(map_, expr->position()))); |
| 112 if (map_or_code->IsCode()) { |
| 113 Handle<Code> code(Code::cast(*map_or_code)); |
| 114 return Handle<Map>(code->FindFirstMap()); |
| 115 } |
| 116 return Handle<Map>(Map::cast(*map_or_code)); |
97 } | 117 } |
98 | 118 |
99 | 119 |
100 Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Assignment* expr) { | 120 Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Assignment* expr) { |
101 ASSERT(StoreIsMonomorphic(expr)); | 121 ASSERT(StoreIsMonomorphic(expr)); |
102 return Handle<Map>::cast(GetElement(map_, expr->position())); | 122 Handle<HeapObject> map_or_code( |
| 123 Handle<HeapObject>::cast(GetElement(map_, expr->position()))); |
| 124 if (map_or_code->IsCode()) { |
| 125 Handle<Code> code(Code::cast(*map_or_code)); |
| 126 return Handle<Map>(code->FindFirstMap()); |
| 127 } |
| 128 return Handle<Map>(Map::cast(*map_or_code)); |
103 } | 129 } |
104 | 130 |
105 | 131 |
106 ZoneMapList* TypeFeedbackOracle::LoadReceiverTypes(Property* expr, | 132 ZoneMapList* TypeFeedbackOracle::LoadReceiverTypes(Property* expr, |
107 Handle<String> name) { | 133 Handle<String> name) { |
108 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); | 134 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); |
109 return CollectReceiverTypes(expr->position(), name, flags); | 135 return CollectReceiverTypes(expr->position(), name, flags); |
110 } | 136 } |
111 | 137 |
112 | 138 |
(...skipping 22 matching lines...) Expand all Loading... |
135 | 161 |
136 | 162 |
137 CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) { | 163 CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) { |
138 Handle<Object> value = GetElement(map_, expr->position()); | 164 Handle<Object> value = GetElement(map_, expr->position()); |
139 if (!value->IsSmi()) return RECEIVER_MAP_CHECK; | 165 if (!value->IsSmi()) return RECEIVER_MAP_CHECK; |
140 CheckType check = static_cast<CheckType>(Smi::cast(*value)->value()); | 166 CheckType check = static_cast<CheckType>(Smi::cast(*value)->value()); |
141 ASSERT(check != RECEIVER_MAP_CHECK); | 167 ASSERT(check != RECEIVER_MAP_CHECK); |
142 return check; | 168 return check; |
143 } | 169 } |
144 | 170 |
| 171 ExternalArrayType TypeFeedbackOracle::GetKeyedLoadExternalArrayType( |
| 172 Property* expr) { |
| 173 Handle<Object> stub = GetElement(map_, expr->position()); |
| 174 ASSERT(stub->IsCode()); |
| 175 return Code::cast(*stub)->external_array_type(); |
| 176 } |
| 177 |
| 178 ExternalArrayType TypeFeedbackOracle::GetKeyedStoreExternalArrayType( |
| 179 Assignment* expr) { |
| 180 Handle<Object> stub = GetElement(map_, expr->position()); |
| 181 ASSERT(stub->IsCode()); |
| 182 return Code::cast(*stub)->external_array_type(); |
| 183 } |
145 | 184 |
146 Handle<JSObject> TypeFeedbackOracle::GetPrototypeForPrimitiveCheck( | 185 Handle<JSObject> TypeFeedbackOracle::GetPrototypeForPrimitiveCheck( |
147 CheckType check) { | 186 CheckType check) { |
148 JSFunction* function = NULL; | 187 JSFunction* function = NULL; |
149 switch (check) { | 188 switch (check) { |
150 case RECEIVER_MAP_CHECK: | 189 case RECEIVER_MAP_CHECK: |
151 UNREACHABLE(); | 190 UNREACHABLE(); |
152 break; | 191 break; |
153 case STRING_CHECK: | 192 case STRING_CHECK: |
154 function = global_context_->string_function(); | 193 function = global_context_->string_function(); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 if (kind == Code::BINARY_OP_IC || | 372 if (kind == Code::BINARY_OP_IC || |
334 kind == Code::TYPE_RECORDING_BINARY_OP_IC || | 373 kind == Code::TYPE_RECORDING_BINARY_OP_IC || |
335 kind == Code::COMPARE_IC) { | 374 kind == Code::COMPARE_IC) { |
336 // TODO(kasperl): Avoid having multiple ICs with the same | 375 // TODO(kasperl): Avoid having multiple ICs with the same |
337 // position by making sure that we have position information | 376 // position by making sure that we have position information |
338 // recorded for all binary ICs. | 377 // recorded for all binary ICs. |
339 if (GetElement(map_, position)->IsUndefined()) { | 378 if (GetElement(map_, position)->IsUndefined()) { |
340 SetElement(map_, position, target, kNonStrictMode); | 379 SetElement(map_, position, target, kNonStrictMode); |
341 } | 380 } |
342 } else if (state == MONOMORPHIC) { | 381 } else if (state == MONOMORPHIC) { |
343 if (target->kind() != Code::CALL_IC || | 382 if (kind == Code::KEYED_EXTERNAL_ARRAY_LOAD_IC || |
344 target->check_type() == RECEIVER_MAP_CHECK) { | 383 kind == Code::KEYED_EXTERNAL_ARRAY_STORE_IC) { |
| 384 SetElement(map_, position, target, kNonStrictMode); |
| 385 } else if (kind != Code::CALL_IC || |
| 386 target->check_type() == RECEIVER_MAP_CHECK) { |
345 Handle<Map> map = Handle<Map>(target->FindFirstMap()); | 387 Handle<Map> map = Handle<Map>(target->FindFirstMap()); |
346 if (*map == NULL) { | 388 if (*map == NULL) { |
347 SetElement(map_, position, target, kNonStrictMode); | 389 SetElement(map_, position, target, kNonStrictMode); |
348 } else { | 390 } else { |
349 SetElement(map_, position, map, kNonStrictMode); | 391 SetElement(map_, position, map, kNonStrictMode); |
350 } | 392 } |
351 } else { | 393 } else { |
352 ASSERT(target->kind() == Code::CALL_IC); | 394 ASSERT(target->kind() == Code::CALL_IC); |
353 CheckType check = target->check_type(); | 395 CheckType check = target->check_type(); |
354 ASSERT(check != RECEIVER_MAP_CHECK); | 396 ASSERT(check != RECEIVER_MAP_CHECK); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 source_positions->Add(position); | 440 source_positions->Add(position); |
399 } | 441 } |
400 } else { | 442 } else { |
401 ASSERT(RelocInfo::IsPosition(mode)); | 443 ASSERT(RelocInfo::IsPosition(mode)); |
402 position = static_cast<int>(info->data()); | 444 position = static_cast<int>(info->data()); |
403 } | 445 } |
404 } | 446 } |
405 } | 447 } |
406 | 448 |
407 } } // namespace v8::internal | 449 } } // namespace v8::internal |
OLD | NEW |