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

Side by Side Diff: src/code-stubs.cc

Issue 10837165: Lattice-based representation inference, powered by left/right specific type feedback for BinaryOps … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback; fixed tests Created 8 years, 1 month 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/code-stubs.h ('k') | src/date.js » ('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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 return NULL; 162 return NULL;
163 } 163 }
164 } 164 }
165 165
166 166
167 void CodeStub::PrintName(StringStream* stream) { 167 void CodeStub::PrintName(StringStream* stream) {
168 stream->Add("%s", MajorName(MajorKey(), false)); 168 stream->Add("%s", MajorName(MajorKey(), false));
169 } 169 }
170 170
171 171
172 void BinaryOpStub::Generate(MacroAssembler* masm) {
173 // Explicitly allow generation of nested stubs. It is safe here because
174 // generation code does not use any raw pointers.
175 AllowStubCallsScope allow_stub_calls(masm, true);
176
177 BinaryOpIC::TypeInfo operands_type = Max(left_type_, right_type_);
178 if (left_type_ == BinaryOpIC::ODDBALL && right_type_ == BinaryOpIC::ODDBALL) {
179 // The OddballStub handles a number and an oddball, not two oddballs.
180 operands_type = BinaryOpIC::GENERIC;
181 }
182 switch (operands_type) {
183 case BinaryOpIC::UNINITIALIZED:
184 GenerateTypeTransition(masm);
185 break;
186 case BinaryOpIC::SMI:
187 GenerateSmiStub(masm);
188 break;
189 case BinaryOpIC::INT32:
190 GenerateInt32Stub(masm);
191 break;
192 case BinaryOpIC::HEAP_NUMBER:
193 GenerateHeapNumberStub(masm);
194 break;
195 case BinaryOpIC::ODDBALL:
196 GenerateOddballStub(masm);
197 break;
198 case BinaryOpIC::STRING:
199 GenerateStringStub(masm);
200 break;
201 case BinaryOpIC::GENERIC:
202 GenerateGeneric(masm);
203 break;
204 default:
205 UNREACHABLE();
206 }
207 }
208
209
210 #define __ ACCESS_MASM(masm)
211
212
213 void BinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) {
214 switch (op_) {
215 case Token::ADD:
216 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION);
217 break;
218 case Token::SUB:
219 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION);
220 break;
221 case Token::MUL:
222 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION);
223 break;
224 case Token::DIV:
225 __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION);
226 break;
227 case Token::MOD:
228 __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
229 break;
230 case Token::BIT_OR:
231 __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION);
232 break;
233 case Token::BIT_AND:
234 __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION);
235 break;
236 case Token::BIT_XOR:
237 __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION);
238 break;
239 case Token::SAR:
240 __ InvokeBuiltin(Builtins::SAR, JUMP_FUNCTION);
241 break;
242 case Token::SHR:
243 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION);
244 break;
245 case Token::SHL:
246 __ InvokeBuiltin(Builtins::SHL, JUMP_FUNCTION);
247 break;
248 default:
249 UNREACHABLE();
250 }
251 }
252
253
254 #undef __
255
256
257 void BinaryOpStub::PrintName(StringStream* stream) {
258 const char* op_name = Token::Name(op_);
259 const char* overwrite_name;
260 switch (mode_) {
261 case NO_OVERWRITE: overwrite_name = "Alloc"; break;
262 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break;
263 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
264 default: overwrite_name = "UnknownOverwrite"; break;
265 }
266 stream->Add("BinaryOpStub_%s_%s_%s+%s",
267 op_name,
268 overwrite_name,
269 BinaryOpIC::GetName(left_type_),
270 BinaryOpIC::GetName(right_type_));
271 }
272
273
274 void BinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
275 ASSERT(left_type_ == BinaryOpIC::STRING || right_type_ == BinaryOpIC::STRING);
276 ASSERT(op_ == Token::ADD);
277 if (left_type_ == BinaryOpIC::STRING && right_type_ == BinaryOpIC::STRING) {
278 GenerateBothStringStub(masm);
279 return;
280 }
281 // Try to add arguments as strings, otherwise, transition to the generic
282 // BinaryOpIC type.
283 GenerateAddStrings(masm);
284 GenerateTypeTransition(masm);
285 }
286
287
172 void ICCompareStub::AddToSpecialCache(Handle<Code> new_object) { 288 void ICCompareStub::AddToSpecialCache(Handle<Code> new_object) {
173 ASSERT(*known_map_ != NULL); 289 ASSERT(*known_map_ != NULL);
174 Isolate* isolate = new_object->GetIsolate(); 290 Isolate* isolate = new_object->GetIsolate();
175 Factory* factory = isolate->factory(); 291 Factory* factory = isolate->factory();
176 return Map::UpdateCodeCache(known_map_, 292 return Map::UpdateCodeCache(known_map_,
177 strict() ? 293 strict() ?
178 factory->strict_compare_ic_symbol() : 294 factory->strict_compare_ic_symbol() :
179 factory->compare_ic_symbol(), 295 factory->compare_ic_symbol(),
180 new_object); 296 new_object);
181 } 297 }
182 298
183 299
184 bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) { 300 bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) {
185 Isolate* isolate = known_map_->GetIsolate(); 301 Isolate* isolate = known_map_->GetIsolate();
186 Factory* factory = isolate->factory(); 302 Factory* factory = isolate->factory();
187 Code::Flags flags = Code::ComputeFlags( 303 Code::Flags flags = Code::ComputeFlags(
188 static_cast<Code::Kind>(GetCodeKind()), 304 static_cast<Code::Kind>(GetCodeKind()),
189 UNINITIALIZED); 305 UNINITIALIZED);
190 ASSERT(op_ == Token::EQ || op_ == Token::EQ_STRICT); 306 ASSERT(op_ == Token::EQ || op_ == Token::EQ_STRICT);
191 Handle<Object> probe( 307 Handle<Object> probe(
192 known_map_->FindInCodeCache( 308 known_map_->FindInCodeCache(
193 strict() ? 309 strict() ?
194 *factory->strict_compare_ic_symbol() : 310 *factory->strict_compare_ic_symbol() :
195 *factory->compare_ic_symbol(), 311 *factory->compare_ic_symbol(),
196 flags)); 312 flags));
197 if (probe->IsCode()) { 313 if (probe->IsCode()) {
198 *code_out = Code::cast(*probe); 314 *code_out = Code::cast(*probe);
199 ASSERT(op_ == (*code_out)->compare_operation() + Token::EQ); 315 #ifdef DEBUG
316 Token::Value cached_op;
317 ICCompareStub::DecodeMinorKey((*code_out)->stub_info(), NULL, NULL, NULL,
318 &cached_op);
319 ASSERT(op_ == cached_op);
320 #endif
200 return true; 321 return true;
201 } 322 }
202 return false; 323 return false;
203 } 324 }
204 325
205 326
206 int ICCompareStub::MinorKey() { 327 int ICCompareStub::MinorKey() {
207 return OpField::encode(op_ - Token::EQ) | StateField::encode(state_); 328 return OpField::encode(op_ - Token::EQ) |
329 LeftStateField::encode(left_) |
330 RightStateField::encode(right_) |
331 HandlerStateField::encode(state_);
208 } 332 }
209 333
210 334
335 void ICCompareStub::DecodeMinorKey(int minor_key,
336 CompareIC::State* left_state,
337 CompareIC::State* right_state,
338 CompareIC::State* handler_state,
339 Token::Value* op) {
340 if (left_state) {
341 *left_state =
342 static_cast<CompareIC::State>(LeftStateField::decode(minor_key));
343 }
344 if (right_state) {
345 *right_state =
346 static_cast<CompareIC::State>(RightStateField::decode(minor_key));
347 }
348 if (handler_state) {
349 *handler_state =
350 static_cast<CompareIC::State>(HandlerStateField::decode(minor_key));
351 }
352 if (op) {
353 *op = static_cast<Token::Value>(OpField::decode(minor_key) + Token::EQ);
354 }
355 }
356
357
211 void ICCompareStub::Generate(MacroAssembler* masm) { 358 void ICCompareStub::Generate(MacroAssembler* masm) {
212 switch (state_) { 359 switch (state_) {
213 case CompareIC::UNINITIALIZED: 360 case CompareIC::UNINITIALIZED:
214 GenerateMiss(masm); 361 GenerateMiss(masm);
215 break; 362 break;
216 case CompareIC::SMIS: 363 case CompareIC::SMI:
217 GenerateSmis(masm); 364 GenerateSmis(masm);
218 break; 365 break;
219 case CompareIC::HEAP_NUMBERS: 366 case CompareIC::HEAP_NUMBER:
220 GenerateHeapNumbers(masm); 367 GenerateHeapNumbers(masm);
221 break; 368 break;
222 case CompareIC::STRINGS: 369 case CompareIC::STRING:
223 GenerateStrings(masm); 370 GenerateStrings(masm);
224 break; 371 break;
225 case CompareIC::SYMBOLS: 372 case CompareIC::SYMBOL:
226 GenerateSymbols(masm); 373 GenerateSymbols(masm);
227 break; 374 break;
228 case CompareIC::OBJECTS: 375 case CompareIC::OBJECT:
229 GenerateObjects(masm); 376 GenerateObjects(masm);
230 break; 377 break;
231 case CompareIC::KNOWN_OBJECTS: 378 case CompareIC::KNOWN_OBJECTS:
232 ASSERT(*known_map_ != NULL); 379 ASSERT(*known_map_ != NULL);
233 GenerateKnownObjects(masm); 380 GenerateKnownObjects(masm);
234 break; 381 break;
235 default: 382 case CompareIC::GENERIC:
236 UNREACHABLE(); 383 GenerateGeneric(masm);
384 break;
237 } 385 }
238 } 386 }
239 387
240 388
241 void InstanceofStub::PrintName(StringStream* stream) { 389 void InstanceofStub::PrintName(StringStream* stream) {
242 const char* args = ""; 390 const char* args = "";
243 if (HasArgsInRegisters()) { 391 if (HasArgsInRegisters()) {
244 args = "_REGS"; 392 args = "_REGS";
245 } 393 }
246 394
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 // already active, as the hooks won't stack. 644 // already active, as the hooks won't stack.
497 if (entry_hook != 0 && entry_hook_ != 0) 645 if (entry_hook != 0 && entry_hook_ != 0)
498 return false; 646 return false;
499 647
500 entry_hook_ = entry_hook; 648 entry_hook_ = entry_hook;
501 return true; 649 return true;
502 } 650 }
503 651
504 652
505 } } // namespace v8::internal 653 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs.h ('k') | src/date.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698