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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 return CollectReceiverTypes(expr->position(), name, flags); | 125 return CollectReceiverTypes(expr->position(), name, flags); |
126 } | 126 } |
127 | 127 |
128 | 128 |
129 bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) { | 129 bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) { |
130 Handle<Object> object = GetElement(map_, expr->position()); | 130 Handle<Object> object = GetElement(map_, expr->position()); |
131 return *object == Builtins::builtin(id); | 131 return *object == Builtins::builtin(id); |
132 } | 132 } |
133 | 133 |
134 | 134 |
135 TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) { | 135 TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr, Side side) { |
136 Handle<Object> object = GetElement(map_, expr->position()); | 136 Handle<Object> object = GetElement(map_, expr->position()); |
137 TypeInfo unknown = TypeInfo::Unknown(); | 137 TypeInfo unknown = TypeInfo::Unknown(); |
138 if (!object->IsCode()) return unknown; | 138 if (!object->IsCode()) return unknown; |
139 Handle<Code> code = Handle<Code>::cast(object); | 139 Handle<Code> code = Handle<Code>::cast(object); |
140 if (!code->is_compare_ic_stub()) return unknown; | 140 if (!code->is_compare_ic_stub()) return unknown; |
141 | 141 |
142 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state()); | 142 CompareIC::State state = static_cast<CompareIC::State>(code->compare_state()); |
143 switch (state) { | 143 switch (state) { |
144 case CompareIC::UNINITIALIZED: | 144 case CompareIC::UNINITIALIZED: |
145 // Uninitialized means never executed. | 145 // Uninitialized means never executed. |
146 // TODO(fschneider): Introduce a separate value for never-executed ICs. | 146 // TODO(fschneider): Introduce a separate value for never-executed ICs. |
147 return unknown; | 147 return unknown; |
148 case CompareIC::SMIS: | 148 case CompareIC::SMIS: |
149 return TypeInfo::Smi(); | 149 return TypeInfo::Smi(); |
150 case CompareIC::HEAP_NUMBERS: | 150 case CompareIC::HEAP_NUMBERS: |
151 return TypeInfo::Number(); | 151 return TypeInfo::Number(); |
152 case CompareIC::OBJECTS: | 152 case CompareIC::OBJECTS: |
153 // TODO(kasperl): We really need a type for JS objects here. | 153 // TODO(kasperl): We really need a type for JS objects here. |
154 return TypeInfo::NonPrimitive(); | 154 return TypeInfo::NonPrimitive(); |
155 case CompareIC::GENERIC: | 155 case CompareIC::GENERIC: |
156 default: | 156 default: |
157 return unknown; | 157 return unknown; |
158 } | 158 } |
159 } | 159 } |
160 | 160 |
161 | 161 |
162 TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) { | 162 TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr, Side side) { |
163 Handle<Object> object = GetElement(map_, expr->position()); | 163 Handle<Object> object = GetElement(map_, expr->position()); |
164 TypeInfo unknown = TypeInfo::Unknown(); | 164 TypeInfo unknown = TypeInfo::Unknown(); |
165 if (!object->IsCode()) return unknown; | 165 if (!object->IsCode()) return unknown; |
166 Handle<Code> code = Handle<Code>::cast(object); | 166 Handle<Code> code = Handle<Code>::cast(object); |
167 if (code->is_type_recording_binary_op_stub()) { | 167 if (code->is_binary_op_stub()) { |
| 168 BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>( |
| 169 code->binary_op_type()); |
| 170 switch (type) { |
| 171 case BinaryOpIC::UNINIT_OR_SMI: |
| 172 return TypeInfo::Smi(); |
| 173 case BinaryOpIC::DEFAULT: |
| 174 return (expr->op() == Token::DIV || expr->op() == Token::MUL) |
| 175 ? TypeInfo::Double() |
| 176 : TypeInfo::Integer32(); |
| 177 case BinaryOpIC::HEAP_NUMBERS: |
| 178 return TypeInfo::Double(); |
| 179 default: |
| 180 return unknown; |
| 181 } |
| 182 } else if (code->is_type_recording_binary_op_stub()) { |
168 TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>( | 183 TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>( |
169 code->type_recording_binary_op_type()); | 184 code->type_recording_binary_op_type()); |
170 TRBinaryOpIC::TypeInfo result_type = static_cast<TRBinaryOpIC::TypeInfo>( | 185 TRBinaryOpIC::TypeInfo result_type = static_cast<TRBinaryOpIC::TypeInfo>( |
171 code->type_recording_binary_op_result_type()); | 186 code->type_recording_binary_op_result_type()); |
172 | 187 |
173 switch (type) { | 188 switch (type) { |
174 case TRBinaryOpIC::UNINITIALIZED: | 189 case TRBinaryOpIC::UNINITIALIZED: |
175 // Uninitialized means never executed. | 190 // Uninitialized means never executed. |
176 // TODO(fschneider): Introduce a separate value for never-executed ICs | 191 // TODO(fschneider): Introduce a separate value for never-executed ICs |
177 return unknown; | 192 return unknown; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 | 284 |
270 int length = code_positions.length(); | 285 int length = code_positions.length(); |
271 ASSERT(source_positions.length() == length); | 286 ASSERT(source_positions.length() == length); |
272 for (int i = 0; i < length; i++) { | 287 for (int i = 0; i < length; i++) { |
273 RelocInfo info(code->instruction_start() + code_positions[i], | 288 RelocInfo info(code->instruction_start() + code_positions[i], |
274 RelocInfo::CODE_TARGET, 0); | 289 RelocInfo::CODE_TARGET, 0); |
275 Handle<Code> target(Code::GetCodeFromTargetAddress(info.target_address())); | 290 Handle<Code> target(Code::GetCodeFromTargetAddress(info.target_address())); |
276 int position = source_positions[i]; | 291 int position = source_positions[i]; |
277 InlineCacheState state = target->ic_state(); | 292 InlineCacheState state = target->ic_state(); |
278 Code::Kind kind = target->kind(); | 293 Code::Kind kind = target->kind(); |
279 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC || | 294 if (kind == Code::BINARY_OP_IC || |
| 295 kind == Code::TYPE_RECORDING_BINARY_OP_IC || |
280 kind == Code::COMPARE_IC) { | 296 kind == Code::COMPARE_IC) { |
281 // TODO(kasperl): Avoid having multiple ICs with the same | 297 // TODO(kasperl): Avoid having multiple ICs with the same |
282 // position by making sure that we have position information | 298 // position by making sure that we have position information |
283 // recorded for all binary ICs. | 299 // recorded for all binary ICs. |
284 if (GetElement(map_, position)->IsUndefined()) { | 300 if (GetElement(map_, position)->IsUndefined()) { |
285 SetElement(map_, position, target); | 301 SetElement(map_, position, target); |
286 } | 302 } |
287 } else if (state == MONOMORPHIC) { | 303 } else if (state == MONOMORPHIC) { |
288 Handle<Map> map = Handle<Map>(target->FindFirstMap()); | 304 Handle<Map> map = Handle<Map>(target->FindFirstMap()); |
289 if (*map == NULL) { | 305 if (*map == NULL) { |
(...skipping 19 matching lines...) Expand all Loading... |
309 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | | 325 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
310 RelocInfo::kPositionMask; | 326 RelocInfo::kPositionMask; |
311 for (RelocIterator it(code, mask); !it.done(); it.next()) { | 327 for (RelocIterator it(code, mask); !it.done(); it.next()) { |
312 RelocInfo* info = it.rinfo(); | 328 RelocInfo* info = it.rinfo(); |
313 RelocInfo::Mode mode = info->rmode(); | 329 RelocInfo::Mode mode = info->rmode(); |
314 if (RelocInfo::IsCodeTarget(mode)) { | 330 if (RelocInfo::IsCodeTarget(mode)) { |
315 Code* target = Code::GetCodeFromTargetAddress(info->target_address()); | 331 Code* target = Code::GetCodeFromTargetAddress(info->target_address()); |
316 if (target->is_inline_cache_stub()) { | 332 if (target->is_inline_cache_stub()) { |
317 InlineCacheState state = target->ic_state(); | 333 InlineCacheState state = target->ic_state(); |
318 Code::Kind kind = target->kind(); | 334 Code::Kind kind = target->kind(); |
319 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC && | 335 if (kind == Code::BINARY_OP_IC) { |
320 target->type_recording_binary_op_type() == TRBinaryOpIC::GENERIC) { | 336 if (target->binary_op_type() == BinaryOpIC::GENERIC) continue; |
321 continue; | 337 } else if (kind == Code::TYPE_RECORDING_BINARY_OP_IC) { |
322 } else if (kind == Code::COMPARE_IC && | 338 if (target->type_recording_binary_op_type() == |
323 target->compare_state() == CompareIC::GENERIC) { | 339 TRBinaryOpIC::GENERIC) { |
324 continue; | 340 continue; |
325 } else if (kind == Code::CALL_IC && state == MONOMORPHIC && | 341 } |
326 target->check_type() != RECEIVER_MAP_CHECK) { | 342 } else if (kind == Code::COMPARE_IC) { |
327 continue; | 343 if (target->compare_state() == CompareIC::GENERIC) continue; |
328 } else if (state != MONOMORPHIC && state != MEGAMORPHIC) { | 344 } else { |
329 continue; | 345 if (kind == Code::CALL_IC && state == MONOMORPHIC && |
| 346 target->check_type() != RECEIVER_MAP_CHECK) continue; |
| 347 if (state != MONOMORPHIC && state != MEGAMORPHIC) continue; |
330 } | 348 } |
331 code_positions->Add( | 349 code_positions->Add( |
332 static_cast<int>(info->pc() - code->instruction_start())); | 350 static_cast<int>(info->pc() - code->instruction_start())); |
333 source_positions->Add(position); | 351 source_positions->Add(position); |
334 } | 352 } |
335 } else { | 353 } else { |
336 ASSERT(RelocInfo::IsPosition(mode)); | 354 ASSERT(RelocInfo::IsPosition(mode)); |
337 position = static_cast<int>(info->data()); | 355 position = static_cast<int>(info->data()); |
338 } | 356 } |
339 } | 357 } |
340 } | 358 } |
341 | 359 |
342 } } // namespace v8::internal | 360 } } // namespace v8::internal |
OLD | NEW |