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, Side side) { | 135 TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) { |
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, Side side) { | 162 TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) { |
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_binary_op_stub()) { | 167 if (code->is_type_recording_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()) { | |
183 TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>( | 168 TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>( |
184 code->type_recording_binary_op_type()); | 169 code->type_recording_binary_op_type()); |
185 TRBinaryOpIC::TypeInfo result_type = static_cast<TRBinaryOpIC::TypeInfo>( | 170 TRBinaryOpIC::TypeInfo result_type = static_cast<TRBinaryOpIC::TypeInfo>( |
186 code->type_recording_binary_op_result_type()); | 171 code->type_recording_binary_op_result_type()); |
187 | 172 |
188 switch (type) { | 173 switch (type) { |
189 case TRBinaryOpIC::UNINITIALIZED: | 174 case TRBinaryOpIC::UNINITIALIZED: |
190 // Uninitialized means never executed. | 175 // Uninitialized means never executed. |
191 // TODO(fschneider): Introduce a separate value for never-executed ICs | 176 // TODO(fschneider): Introduce a separate value for never-executed ICs |
192 return unknown; | 177 return unknown; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 | 269 |
285 int length = code_positions.length(); | 270 int length = code_positions.length(); |
286 ASSERT(source_positions.length() == length); | 271 ASSERT(source_positions.length() == length); |
287 for (int i = 0; i < length; i++) { | 272 for (int i = 0; i < length; i++) { |
288 RelocInfo info(code->instruction_start() + code_positions[i], | 273 RelocInfo info(code->instruction_start() + code_positions[i], |
289 RelocInfo::CODE_TARGET, 0); | 274 RelocInfo::CODE_TARGET, 0); |
290 Handle<Code> target(Code::GetCodeFromTargetAddress(info.target_address())); | 275 Handle<Code> target(Code::GetCodeFromTargetAddress(info.target_address())); |
291 int position = source_positions[i]; | 276 int position = source_positions[i]; |
292 InlineCacheState state = target->ic_state(); | 277 InlineCacheState state = target->ic_state(); |
293 Code::Kind kind = target->kind(); | 278 Code::Kind kind = target->kind(); |
294 if (kind == Code::BINARY_OP_IC || | 279 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC || |
295 kind == Code::TYPE_RECORDING_BINARY_OP_IC || | |
296 kind == Code::COMPARE_IC) { | 280 kind == Code::COMPARE_IC) { |
297 // TODO(kasperl): Avoid having multiple ICs with the same | 281 // TODO(kasperl): Avoid having multiple ICs with the same |
298 // position by making sure that we have position information | 282 // position by making sure that we have position information |
299 // recorded for all binary ICs. | 283 // recorded for all binary ICs. |
300 if (GetElement(map_, position)->IsUndefined()) { | 284 if (GetElement(map_, position)->IsUndefined()) { |
301 SetElement(map_, position, target); | 285 SetElement(map_, position, target); |
302 } | 286 } |
303 } else if (state == MONOMORPHIC) { | 287 } else if (state == MONOMORPHIC) { |
304 Handle<Map> map = Handle<Map>(target->FindFirstMap()); | 288 Handle<Map> map = Handle<Map>(target->FindFirstMap()); |
305 if (*map == NULL) { | 289 if (*map == NULL) { |
(...skipping 19 matching lines...) Expand all Loading... |
325 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | | 309 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
326 RelocInfo::kPositionMask; | 310 RelocInfo::kPositionMask; |
327 for (RelocIterator it(code, mask); !it.done(); it.next()) { | 311 for (RelocIterator it(code, mask); !it.done(); it.next()) { |
328 RelocInfo* info = it.rinfo(); | 312 RelocInfo* info = it.rinfo(); |
329 RelocInfo::Mode mode = info->rmode(); | 313 RelocInfo::Mode mode = info->rmode(); |
330 if (RelocInfo::IsCodeTarget(mode)) { | 314 if (RelocInfo::IsCodeTarget(mode)) { |
331 Code* target = Code::GetCodeFromTargetAddress(info->target_address()); | 315 Code* target = Code::GetCodeFromTargetAddress(info->target_address()); |
332 if (target->is_inline_cache_stub()) { | 316 if (target->is_inline_cache_stub()) { |
333 InlineCacheState state = target->ic_state(); | 317 InlineCacheState state = target->ic_state(); |
334 Code::Kind kind = target->kind(); | 318 Code::Kind kind = target->kind(); |
335 if (kind == Code::BINARY_OP_IC) { | 319 if (kind == Code::TYPE_RECORDING_BINARY_OP_IC && |
336 if (target->binary_op_type() == BinaryOpIC::GENERIC) continue; | 320 target->type_recording_binary_op_type() == TRBinaryOpIC::GENERIC) { |
337 } else if (kind == Code::TYPE_RECORDING_BINARY_OP_IC) { | 321 continue; |
338 if (target->type_recording_binary_op_type() == | 322 } else if (kind == Code::COMPARE_IC && |
339 TRBinaryOpIC::GENERIC) { | 323 target->compare_state() == CompareIC::GENERIC) { |
340 continue; | 324 continue; |
341 } | 325 } else if (kind == Code::CALL_IC && state == MONOMORPHIC && |
342 } else if (kind == Code::COMPARE_IC) { | 326 target->check_type() != RECEIVER_MAP_CHECK) { |
343 if (target->compare_state() == CompareIC::GENERIC) continue; | 327 continue; |
344 } else { | 328 } else if (state != MONOMORPHIC && state != MEGAMORPHIC) { |
345 if (kind == Code::CALL_IC && state == MONOMORPHIC && | 329 continue; |
346 target->check_type() != RECEIVER_MAP_CHECK) continue; | |
347 if (state != MONOMORPHIC && state != MEGAMORPHIC) continue; | |
348 } | 330 } |
349 code_positions->Add( | 331 code_positions->Add( |
350 static_cast<int>(info->pc() - code->instruction_start())); | 332 static_cast<int>(info->pc() - code->instruction_start())); |
351 source_positions->Add(position); | 333 source_positions->Add(position); |
352 } | 334 } |
353 } else { | 335 } else { |
354 ASSERT(RelocInfo::IsPosition(mode)); | 336 ASSERT(RelocInfo::IsPosition(mode)); |
355 position = static_cast<int>(info->data()); | 337 position = static_cast<int>(info->data()); |
356 } | 338 } |
357 } | 339 } |
358 } | 340 } |
359 | 341 |
360 } } // namespace v8::internal | 342 } } // namespace v8::internal |
OLD | NEW |