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

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

Issue 97543002: Refactor BinaryOpIC to be able to use different stubs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 7 years 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
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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 stream->Add("%s", MajorName(MajorKey(), false)); 210 stream->Add("%s", MajorName(MajorKey(), false));
211 } 211 }
212 212
213 213
214 void CodeStub::PrintName(StringStream* stream) { 214 void CodeStub::PrintName(StringStream* stream) {
215 PrintBaseName(stream); 215 PrintBaseName(stream);
216 PrintState(stream); 216 PrintState(stream);
217 } 217 }
218 218
219 219
220 void BinaryOpStub::PrintBaseName(StringStream* stream) { 220 // static
221 const char* op_name = Token::Name(op_); 221 void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) {
222 const char* ovr = ""; 222 // Generate the uninitialized versions of the stub.
223 if (mode_ == OVERWRITE_LEFT) ovr = "_ReuseLeft"; 223 for (int op = Token::BIT_OR; op <= Token::MOD; ++op) {
224 if (mode_ == OVERWRITE_RIGHT) ovr = "_ReuseRight"; 224 for (int mode = NO_OVERWRITE; mode <= OVERWRITE_RIGHT; ++mode) {
225 stream->Add("BinaryOpStub_%s%s", op_name, ovr); 225 BinaryOpICStub stub(static_cast<Token::Value>(op),
226 static_cast<OverwriteMode>(mode));
227 stub.GetCode(isolate);
228 }
229 }
230
231 // Generate special versions of the stub.
232 BinaryOpIC::State::GenerateAheadOfTime(isolate, &GenerateAheadOfTime);
226 } 233 }
227 234
228 235
229 void BinaryOpStub::PrintState(StringStream* stream) { 236 void BinaryOpICStub::PrintState(StringStream* stream) {
230 stream->Add("("); 237 state_.Print(stream);
231 stream->Add(StateToName(left_state_));
232 stream->Add("*");
233 if (fixed_right_arg_.has_value) {
234 stream->Add("%d", fixed_right_arg_.value);
235 } else {
236 stream->Add(StateToName(right_state_));
237 }
238 stream->Add("->");
239 stream->Add(StateToName(result_state_));
240 stream->Add(")");
241 } 238 }
242 239
243 240
244 Maybe<Handle<Object> > BinaryOpStub::Result(Handle<Object> left, 241 // static
245 Handle<Object> right, 242 void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate,
246 Isolate* isolate) { 243 const BinaryOpIC::State& state) {
247 Handle<JSBuiltinsObject> builtins(isolate->js_builtins_object()); 244 BinaryOpICStub stub(state);
248 Builtins::JavaScript func = BinaryOpIC::TokenToJSBuiltin(op_);
249 Object* builtin = builtins->javascript_builtin(func);
250 Handle<JSFunction> builtin_function =
251 Handle<JSFunction>(JSFunction::cast(builtin), isolate);
252 bool caught_exception;
253 Handle<Object> result = Execution::Call(isolate, builtin_function, left,
254 1, &right, &caught_exception);
255 return Maybe<Handle<Object> >(!caught_exception, result);
256 }
257
258
259 void BinaryOpStub::Initialize() {
260 fixed_right_arg_.has_value = false;
261 left_state_ = right_state_ = result_state_ = NONE;
262 }
263
264
265 void BinaryOpStub::Generate(Token::Value op,
266 State left,
267 State right,
268 State result,
269 OverwriteMode mode,
270 Isolate* isolate) {
271 BinaryOpStub stub(INITIALIZED);
272 stub.op_ = op;
273 stub.left_state_ = left;
274 stub.right_state_ = right;
275 stub.result_state_ = result;
276 stub.mode_ = mode;
277 stub.GetCode(isolate); 245 stub.GetCode(isolate);
278 } 246 }
279 247
280 248
281 void BinaryOpStub::Generate(Token::Value op,
282 State left,
283 int right,
284 State result,
285 OverwriteMode mode,
286 Isolate* isolate) {
287 BinaryOpStub stub(INITIALIZED);
288 stub.op_ = op;
289 stub.left_state_ = left;
290 stub.fixed_right_arg_.has_value = true;
291 stub.fixed_right_arg_.value = right;
292 stub.right_state_ = SMI;
293 stub.result_state_ = result;
294 stub.mode_ = mode;
295 stub.GetCode(isolate);
296 }
297
298
299 void BinaryOpStub::GenerateAheadOfTime(Isolate* isolate) {
300 Token::Value binop[] = {Token::SUB, Token::MOD, Token::DIV, Token::MUL,
301 Token::ADD, Token::SAR, Token::BIT_OR, Token::BIT_AND,
302 Token::BIT_XOR, Token::SHL, Token::SHR};
303 for (unsigned i = 0; i < ARRAY_SIZE(binop); i++) {
304 BinaryOpStub stub(UNINITIALIZED);
305 stub.op_ = binop[i];
306 stub.GetCode(isolate);
307 }
308
309 // TODO(olivf) We should investigate why adding stubs to the snapshot is so
310 // expensive at runtime. When solved we should be able to add most binops to
311 // the snapshot instead of hand-picking them.
312 // Generated list of commonly used stubs
313 Generate(Token::ADD, INT32, INT32, INT32, NO_OVERWRITE, isolate);
314 Generate(Token::ADD, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
315 Generate(Token::ADD, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
316 Generate(Token::ADD, INT32, INT32, NUMBER, OVERWRITE_LEFT, isolate);
317 Generate(Token::ADD, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
318 Generate(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
319 Generate(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
320 Generate(Token::ADD, INT32, SMI, INT32, NO_OVERWRITE, isolate);
321 Generate(Token::ADD, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
322 Generate(Token::ADD, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
323 Generate(Token::ADD, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
324 Generate(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
325 Generate(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT, isolate);
326 Generate(Token::ADD, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
327 Generate(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
328 Generate(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
329 Generate(Token::ADD, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
330 Generate(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
331 Generate(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
332 Generate(Token::ADD, SMI, INT32, INT32, NO_OVERWRITE, isolate);
333 Generate(Token::ADD, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
334 Generate(Token::ADD, SMI, INT32, NUMBER, NO_OVERWRITE, isolate);
335 Generate(Token::ADD, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
336 Generate(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
337 Generate(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
338 Generate(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT, isolate);
339 Generate(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
340 Generate(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE, isolate);
341 Generate(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
342 Generate(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
343 Generate(Token::BIT_AND, INT32, INT32, SMI, NO_OVERWRITE, isolate);
344 Generate(Token::BIT_AND, INT32, INT32, SMI, OVERWRITE_RIGHT, isolate);
345 Generate(Token::BIT_AND, INT32, SMI, INT32, NO_OVERWRITE, isolate);
346 Generate(Token::BIT_AND, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
347 Generate(Token::BIT_AND, INT32, SMI, SMI, NO_OVERWRITE, isolate);
348 Generate(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_LEFT, isolate);
349 Generate(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
350 Generate(Token::BIT_AND, NUMBER, INT32, INT32, OVERWRITE_RIGHT, isolate);
351 Generate(Token::BIT_AND, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
352 Generate(Token::BIT_AND, NUMBER, SMI, SMI, OVERWRITE_RIGHT, isolate);
353 Generate(Token::BIT_AND, SMI, INT32, INT32, NO_OVERWRITE, isolate);
354 Generate(Token::BIT_AND, SMI, INT32, SMI, OVERWRITE_RIGHT, isolate);
355 Generate(Token::BIT_AND, SMI, NUMBER, SMI, OVERWRITE_RIGHT, isolate);
356 Generate(Token::BIT_AND, SMI, SMI, SMI, NO_OVERWRITE, isolate);
357 Generate(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
358 Generate(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
359 Generate(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
360 Generate(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
361 Generate(Token::BIT_OR, INT32, INT32, SMI, OVERWRITE_LEFT, isolate);
362 Generate(Token::BIT_OR, INT32, SMI, INT32, NO_OVERWRITE, isolate);
363 Generate(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
364 Generate(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
365 Generate(Token::BIT_OR, INT32, SMI, SMI, NO_OVERWRITE, isolate);
366 Generate(Token::BIT_OR, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
367 Generate(Token::BIT_OR, NUMBER, SMI, INT32, NO_OVERWRITE, isolate);
368 Generate(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_LEFT, isolate);
369 Generate(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_RIGHT, isolate);
370 Generate(Token::BIT_OR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
371 Generate(Token::BIT_OR, NUMBER, SMI, SMI, OVERWRITE_LEFT, isolate);
372 Generate(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
373 Generate(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_RIGHT, isolate);
374 Generate(Token::BIT_OR, SMI, INT32, SMI, OVERWRITE_RIGHT, isolate);
375 Generate(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
376 Generate(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
377 Generate(Token::BIT_XOR, INT32, INT32, INT32, NO_OVERWRITE, isolate);
378 Generate(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
379 Generate(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
380 Generate(Token::BIT_XOR, INT32, INT32, SMI, NO_OVERWRITE, isolate);
381 Generate(Token::BIT_XOR, INT32, INT32, SMI, OVERWRITE_LEFT, isolate);
382 Generate(Token::BIT_XOR, INT32, NUMBER, SMI, NO_OVERWRITE, isolate);
383 Generate(Token::BIT_XOR, INT32, SMI, INT32, NO_OVERWRITE, isolate);
384 Generate(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
385 Generate(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
386 Generate(Token::BIT_XOR, NUMBER, INT32, INT32, NO_OVERWRITE, isolate);
387 Generate(Token::BIT_XOR, NUMBER, SMI, INT32, NO_OVERWRITE, isolate);
388 Generate(Token::BIT_XOR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
389 Generate(Token::BIT_XOR, SMI, INT32, INT32, NO_OVERWRITE, isolate);
390 Generate(Token::BIT_XOR, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
391 Generate(Token::BIT_XOR, SMI, INT32, SMI, OVERWRITE_LEFT, isolate);
392 Generate(Token::BIT_XOR, SMI, SMI, SMI, NO_OVERWRITE, isolate);
393 Generate(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
394 Generate(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
395 Generate(Token::DIV, INT32, INT32, INT32, NO_OVERWRITE, isolate);
396 Generate(Token::DIV, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
397 Generate(Token::DIV, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
398 Generate(Token::DIV, INT32, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
399 Generate(Token::DIV, INT32, SMI, INT32, NO_OVERWRITE, isolate);
400 Generate(Token::DIV, INT32, SMI, NUMBER, NO_OVERWRITE, isolate);
401 Generate(Token::DIV, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
402 Generate(Token::DIV, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
403 Generate(Token::DIV, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
404 Generate(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
405 Generate(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
406 Generate(Token::DIV, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
407 Generate(Token::DIV, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
408 Generate(Token::DIV, SMI, INT32, INT32, NO_OVERWRITE, isolate);
409 Generate(Token::DIV, SMI, INT32, NUMBER, NO_OVERWRITE, isolate);
410 Generate(Token::DIV, SMI, INT32, NUMBER, OVERWRITE_LEFT, isolate);
411 Generate(Token::DIV, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
412 Generate(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
413 Generate(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
414 Generate(Token::DIV, SMI, SMI, NUMBER, NO_OVERWRITE, isolate);
415 Generate(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_LEFT, isolate);
416 Generate(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
417 Generate(Token::DIV, SMI, SMI, SMI, NO_OVERWRITE, isolate);
418 Generate(Token::DIV, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
419 Generate(Token::DIV, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
420 Generate(Token::MOD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
421 Generate(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT, isolate);
422 Generate(Token::MOD, SMI, 2, SMI, NO_OVERWRITE, isolate);
423 Generate(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE, isolate);
424 Generate(Token::MOD, SMI, 32, SMI, NO_OVERWRITE, isolate);
425 Generate(Token::MOD, SMI, 4, SMI, NO_OVERWRITE, isolate);
426 Generate(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT, isolate);
427 Generate(Token::MOD, SMI, 8, SMI, NO_OVERWRITE, isolate);
428 Generate(Token::MOD, SMI, SMI, SMI, NO_OVERWRITE, isolate);
429 Generate(Token::MOD, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
430 Generate(Token::MUL, INT32, INT32, INT32, NO_OVERWRITE, isolate);
431 Generate(Token::MUL, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
432 Generate(Token::MUL, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
433 Generate(Token::MUL, INT32, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
434 Generate(Token::MUL, INT32, SMI, INT32, NO_OVERWRITE, isolate);
435 Generate(Token::MUL, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
436 Generate(Token::MUL, INT32, SMI, NUMBER, NO_OVERWRITE, isolate);
437 Generate(Token::MUL, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
438 Generate(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
439 Generate(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT, isolate);
440 Generate(Token::MUL, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
441 Generate(Token::MUL, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
442 Generate(Token::MUL, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
443 Generate(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
444 Generate(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
445 Generate(Token::MUL, SMI, INT32, INT32, NO_OVERWRITE, isolate);
446 Generate(Token::MUL, SMI, INT32, INT32, OVERWRITE_LEFT, isolate);
447 Generate(Token::MUL, SMI, INT32, NUMBER, NO_OVERWRITE, isolate);
448 Generate(Token::MUL, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
449 Generate(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
450 Generate(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
451 Generate(Token::MUL, SMI, SMI, INT32, NO_OVERWRITE, isolate);
452 Generate(Token::MUL, SMI, SMI, NUMBER, NO_OVERWRITE, isolate);
453 Generate(Token::MUL, SMI, SMI, NUMBER, OVERWRITE_LEFT, isolate);
454 Generate(Token::MUL, SMI, SMI, SMI, NO_OVERWRITE, isolate);
455 Generate(Token::MUL, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
456 Generate(Token::MUL, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
457 Generate(Token::SAR, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
458 Generate(Token::SAR, INT32, SMI, SMI, NO_OVERWRITE, isolate);
459 Generate(Token::SAR, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
460 Generate(Token::SAR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
461 Generate(Token::SAR, NUMBER, SMI, SMI, OVERWRITE_RIGHT, isolate);
462 Generate(Token::SAR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
463 Generate(Token::SAR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
464 Generate(Token::SHL, INT32, SMI, INT32, NO_OVERWRITE, isolate);
465 Generate(Token::SHL, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
466 Generate(Token::SHL, INT32, SMI, SMI, NO_OVERWRITE, isolate);
467 Generate(Token::SHL, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
468 Generate(Token::SHL, NUMBER, SMI, SMI, OVERWRITE_RIGHT, isolate);
469 Generate(Token::SHL, SMI, SMI, INT32, NO_OVERWRITE, isolate);
470 Generate(Token::SHL, SMI, SMI, INT32, OVERWRITE_LEFT, isolate);
471 Generate(Token::SHL, SMI, SMI, INT32, OVERWRITE_RIGHT, isolate);
472 Generate(Token::SHL, SMI, SMI, SMI, NO_OVERWRITE, isolate);
473 Generate(Token::SHL, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
474 Generate(Token::SHL, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
475 Generate(Token::SHR, INT32, SMI, SMI, NO_OVERWRITE, isolate);
476 Generate(Token::SHR, INT32, SMI, SMI, OVERWRITE_LEFT, isolate);
477 Generate(Token::SHR, INT32, SMI, SMI, OVERWRITE_RIGHT, isolate);
478 Generate(Token::SHR, NUMBER, SMI, SMI, NO_OVERWRITE, isolate);
479 Generate(Token::SHR, NUMBER, SMI, SMI, OVERWRITE_LEFT, isolate);
480 Generate(Token::SHR, NUMBER, SMI, INT32, OVERWRITE_RIGHT, isolate);
481 Generate(Token::SHR, SMI, SMI, SMI, NO_OVERWRITE, isolate);
482 Generate(Token::SHR, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
483 Generate(Token::SHR, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
484 Generate(Token::SUB, INT32, INT32, INT32, NO_OVERWRITE, isolate);
485 Generate(Token::SUB, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
486 Generate(Token::SUB, INT32, NUMBER, NUMBER, NO_OVERWRITE, isolate);
487 Generate(Token::SUB, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
488 Generate(Token::SUB, INT32, SMI, INT32, OVERWRITE_LEFT, isolate);
489 Generate(Token::SUB, INT32, SMI, INT32, OVERWRITE_RIGHT, isolate);
490 Generate(Token::SUB, NUMBER, INT32, NUMBER, NO_OVERWRITE, isolate);
491 Generate(Token::SUB, NUMBER, INT32, NUMBER, OVERWRITE_LEFT, isolate);
492 Generate(Token::SUB, NUMBER, NUMBER, NUMBER, NO_OVERWRITE, isolate);
493 Generate(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
494 Generate(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
495 Generate(Token::SUB, NUMBER, SMI, NUMBER, NO_OVERWRITE, isolate);
496 Generate(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_LEFT, isolate);
497 Generate(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT, isolate);
498 Generate(Token::SUB, SMI, INT32, INT32, NO_OVERWRITE, isolate);
499 Generate(Token::SUB, SMI, NUMBER, NUMBER, NO_OVERWRITE, isolate);
500 Generate(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_LEFT, isolate);
501 Generate(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
502 Generate(Token::SUB, SMI, SMI, SMI, NO_OVERWRITE, isolate);
503 Generate(Token::SUB, SMI, SMI, SMI, OVERWRITE_LEFT, isolate);
504 Generate(Token::SUB, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
505 }
506
507
508 bool BinaryOpStub::can_encode_arg_value(int32_t value) const {
509 return op_ == Token::MOD && value > 0 && IsPowerOf2(value) &&
510 FixedRightArgValueBits::is_valid(WhichPowerOf2(value));
511 }
512
513
514 int BinaryOpStub::encode_arg_value(int32_t value) const {
515 ASSERT(can_encode_arg_value(value));
516 return WhichPowerOf2(value);
517 }
518
519
520 int32_t BinaryOpStub::decode_arg_value(int value) const {
521 return 1 << value;
522 }
523
524
525 int BinaryOpStub::encode_token(Token::Value op) const {
526 ASSERT(op >= FIRST_TOKEN && op <= LAST_TOKEN);
527 return op - FIRST_TOKEN;
528 }
529
530
531 Token::Value BinaryOpStub::decode_token(int op) const {
532 int res = op + FIRST_TOKEN;
533 ASSERT(res >= FIRST_TOKEN && res <= LAST_TOKEN);
534 return static_cast<Token::Value>(res);
535 }
536
537
538 const char* BinaryOpStub::StateToName(State state) {
539 switch (state) {
540 case NONE:
541 return "None";
542 case SMI:
543 return "Smi";
544 case INT32:
545 return "Int32";
546 case NUMBER:
547 return "Number";
548 case STRING:
549 return "String";
550 case GENERIC:
551 return "Generic";
552 }
553 return "";
554 }
555
556
557 void BinaryOpStub::UpdateStatus(Handle<Object> left,
558 Handle<Object> right,
559 Maybe<Handle<Object> > result) {
560 int old_state = GetExtraICState();
561
562 UpdateStatus(left, &left_state_);
563 UpdateStatus(right, &right_state_);
564
565 int32_t value;
566 bool new_has_fixed_right_arg =
567 right->ToInt32(&value) && can_encode_arg_value(value) &&
568 (left_state_ == SMI || left_state_ == INT32) &&
569 (result_state_ == NONE || !fixed_right_arg_.has_value);
570
571 fixed_right_arg_ = Maybe<int32_t>(new_has_fixed_right_arg, value);
572
573 if (result.has_value) UpdateStatus(result.value, &result_state_);
574
575 State max_input = Max(left_state_, right_state_);
576
577 if (!has_int_result() && op_ != Token::SHR &&
578 max_input <= NUMBER && max_input > result_state_) {
579 result_state_ = max_input;
580 }
581
582 ASSERT(result_state_ <= (has_int_result() ? INT32 : NUMBER) ||
583 op_ == Token::ADD);
584
585 // Reset overwrite mode unless we can actually make use of it, or may be able
586 // to make use of it at some point in the future.
587 if ((mode_ == OVERWRITE_LEFT && left_state_ > NUMBER) ||
588 (mode_ == OVERWRITE_RIGHT && right_state_ > NUMBER) ||
589 result_state_ > NUMBER) {
590 mode_ = NO_OVERWRITE;
591 }
592
593 if (old_state == GetExtraICState()) {
594 // Tagged operations can lead to non-truncating HChanges
595 if (left->IsUndefined() || left->IsBoolean()) {
596 left_state_ = GENERIC;
597 } else if (right->IsUndefined() || right->IsBoolean()) {
598 right_state_ = GENERIC;
599 } else {
600 // Since the fpu is to precise, we might bail out on numbers which
601 // actually would truncate with 64 bit precision.
602 ASSERT(!CpuFeatures::IsSupported(SSE2) &&
603 result_state_ <= INT32);
604 result_state_ = NUMBER;
605 }
606 }
607 }
608
609
610 void BinaryOpStub::UpdateStatus(Handle<Object> object,
611 State* state) {
612 bool is_truncating = (op_ == Token::BIT_AND || op_ == Token::BIT_OR ||
613 op_ == Token::BIT_XOR || op_ == Token::SAR ||
614 op_ == Token::SHL || op_ == Token::SHR);
615 v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(object);
616 if (object->IsBoolean() && is_truncating) {
617 // Booleans are converted by truncating by HChange.
618 type = TypeInfo::Integer32();
619 }
620 if (object->IsUndefined()) {
621 // Undefined will be automatically truncated for us by HChange.
622 type = is_truncating ? TypeInfo::Integer32() : TypeInfo::Double();
623 }
624 State int_state = SmiValuesAre32Bits() ? NUMBER : INT32;
625 State new_state = NONE;
626 if (type.IsSmi()) {
627 new_state = SMI;
628 } else if (type.IsInteger32()) {
629 new_state = int_state;
630 } else if (type.IsNumber()) {
631 new_state = NUMBER;
632 } else if (object->IsString() && operation() == Token::ADD) {
633 new_state = STRING;
634 } else {
635 new_state = GENERIC;
636 }
637 if ((new_state <= NUMBER && *state > NUMBER) ||
638 (new_state > NUMBER && *state <= NUMBER && *state != NONE)) {
639 new_state = GENERIC;
640 }
641 *state = Max(*state, new_state);
642 }
643
644
645 Handle<Type> BinaryOpStub::StateToType(State state,
646 Isolate* isolate) {
647 Handle<Type> t = handle(Type::None(), isolate);
648 switch (state) {
649 case NUMBER:
650 t = handle(Type::Union(t, handle(Type::Double(), isolate)), isolate);
651 // Fall through.
652 case INT32:
653 t = handle(Type::Union(t, handle(Type::Signed32(), isolate)), isolate);
654 // Fall through.
655 case SMI:
656 t = handle(Type::Union(t, handle(Type::Smi(), isolate)), isolate);
657 break;
658
659 case STRING:
660 t = handle(Type::Union(t, handle(Type::String(), isolate)), isolate);
661 break;
662 case GENERIC:
663 return handle(Type::Any(), isolate);
664 break;
665 case NONE:
666 break;
667 }
668 return t;
669 }
670
671
672 Handle<Type> BinaryOpStub::GetLeftType(Isolate* isolate) const {
673 return StateToType(left_state_, isolate);
674 }
675
676
677 Handle<Type> BinaryOpStub::GetRightType(Isolate* isolate) const {
678 return StateToType(right_state_, isolate);
679 }
680
681
682 Handle<Type> BinaryOpStub::GetResultType(Isolate* isolate) const {
683 if (HasSideEffects(isolate)) return StateToType(NONE, isolate);
684 if (result_state_ == GENERIC && op_ == Token::ADD) {
685 return handle(Type::Union(handle(Type::Number(), isolate),
686 handle(Type::String(), isolate)), isolate);
687 }
688 ASSERT(result_state_ != GENERIC);
689 if (result_state_ == NUMBER && op_ == Token::SHR) {
690 return handle(Type::Unsigned32(), isolate);
691 }
692 return StateToType(result_state_, isolate);
693 }
694
695
696 void NewStringAddStub::PrintBaseName(StringStream* stream) { 249 void NewStringAddStub::PrintBaseName(StringStream* stream) {
697 stream->Add("NewStringAddStub"); 250 stream->Add("NewStringAddStub");
698 if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) { 251 if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) {
699 stream->Add("_CheckBoth"); 252 stream->Add("_CheckBoth");
700 } else if ((flags() & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) { 253 } else if ((flags() & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) {
701 stream->Add("_CheckLeft"); 254 stream->Add("_CheckLeft");
702 } else if ((flags() & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) { 255 } else if ((flags() & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) {
703 stream->Add("_CheckRight"); 256 stream->Add("_CheckRight");
704 } 257 }
705 if (pretenure_flag() == TENURED) { 258 if (pretenure_flag() == TENURED) {
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 } 712 }
1160 713
1161 714
1162 void FastNewClosureStub::InstallDescriptors(Isolate* isolate) { 715 void FastNewClosureStub::InstallDescriptors(Isolate* isolate) {
1163 FastNewClosureStub stub(STRICT_MODE, false); 716 FastNewClosureStub stub(STRICT_MODE, false);
1164 InstallDescriptor(isolate, &stub); 717 InstallDescriptor(isolate, &stub);
1165 } 718 }
1166 719
1167 720
1168 // static 721 // static
722 void BinaryOpICStub::InstallDescriptors(Isolate* isolate) {
723 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE);
724 InstallDescriptor(isolate, &stub);
725 }
726
727
728 // static
1169 void NewStringAddStub::InstallDescriptors(Isolate* isolate) { 729 void NewStringAddStub::InstallDescriptors(Isolate* isolate) {
1170 NewStringAddStub stub(STRING_ADD_CHECK_NONE, NOT_TENURED); 730 NewStringAddStub stub(STRING_ADD_CHECK_NONE, NOT_TENURED);
1171 InstallDescriptor(isolate, &stub); 731 InstallDescriptor(isolate, &stub);
1172 } 732 }
1173 733
1174 734
1175 ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate) 735 ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate)
1176 : argument_count_(ANY) { 736 : argument_count_(ANY) {
1177 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); 737 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
1178 } 738 }
(...skipping 23 matching lines...) Expand all
1202 InstallDescriptor(isolate, &stub3); 762 InstallDescriptor(isolate, &stub3);
1203 } 763 }
1204 764
1205 InternalArrayConstructorStub::InternalArrayConstructorStub( 765 InternalArrayConstructorStub::InternalArrayConstructorStub(
1206 Isolate* isolate) { 766 Isolate* isolate) {
1207 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); 767 InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
1208 } 768 }
1209 769
1210 770
1211 } } // namespace v8::internal 771 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs.h ('k') | src/code-stubs-hydrogen.cc » ('j') | src/log.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698