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

Side by Side Diff: src/runtime.cc

Issue 598072: Direct call C++ functions (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 months 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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 #include "platform.h" 42 #include "platform.h"
43 #include "runtime.h" 43 #include "runtime.h"
44 #include "scopeinfo.h" 44 #include "scopeinfo.h"
45 #include "smart-pointer.h" 45 #include "smart-pointer.h"
46 #include "stub-cache.h" 46 #include "stub-cache.h"
47 #include "v8threads.h" 47 #include "v8threads.h"
48 48
49 namespace v8 { 49 namespace v8 {
50 namespace internal { 50 namespace internal {
51 51
52 #if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_IA32)
53 #define DIRECT_CALL_SUPPORTED
54 #endif
52 55
53 #define RUNTIME_ASSERT(value) \ 56 #define RUNTIME_ASSERT(value) \
54 if (!(value)) return Top::ThrowIllegalOperation(); 57 if (!(value)) return Top::ThrowIllegalOperation();
55 58
56 // Cast the given object to a value of the specified type and store 59 // Cast the given object to a value of the specified type and store
57 // it in a variable with the given name. If the object is not of the 60 // it in a variable with the given name. If the object is not of the
58 // expected type call IllegalOperation and return. 61 // expected type call IllegalOperation and return.
59 #define CONVERT_CHECKED(Type, name, obj) \ 62 #define CONVERT_CHECKED(Type, name, obj) \
60 RUNTIME_ASSERT(obj->Is##Type()); \ 63 RUNTIME_ASSERT(obj->Is##Type()); \
61 Type* name = Type::cast(obj); 64 Type* name = Type::cast(obj);
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 Top::context()->global_context()->context_extension_function(); 483 Top::context()->global_context()->context_extension_function();
481 Object* object = Heap::AllocateJSObject(constructor); 484 Object* object = Heap::AllocateJSObject(constructor);
482 if (object->IsFailure()) return object; 485 if (object->IsFailure()) return object;
483 // Assign the exception value to the catch variable and make sure 486 // Assign the exception value to the catch variable and make sure
484 // that the catch variable is DontDelete. 487 // that the catch variable is DontDelete.
485 value = JSObject::cast(object)->SetProperty(key, value, DONT_DELETE); 488 value = JSObject::cast(object)->SetProperty(key, value, DONT_DELETE);
486 if (value->IsFailure()) return value; 489 if (value->IsFailure()) return value;
487 return object; 490 return object;
488 } 491 }
489 492
490 493 #ifdef DIRECT_CALL_SUPPORTED
494 static Object* Runtime_ClassOf(Object* obj) {
495 AssertNoAllocation na;
496 #else
491 static Object* Runtime_ClassOf(Arguments args) { 497 static Object* Runtime_ClassOf(Arguments args) {
492 NoHandleAllocation ha; 498 NoHandleAllocation ha;
493 ASSERT(args.length() == 1); 499 ASSERT(args.length() == 1);
494 Object* obj = args[0]; 500 Object* obj = args[0];
501 #endif
495 if (!obj->IsJSObject()) return Heap::null_value(); 502 if (!obj->IsJSObject()) return Heap::null_value();
496 return JSObject::cast(obj)->class_name(); 503 return JSObject::cast(obj)->class_name();
497 } 504 }
498 505
499 506
507 #ifdef DIRECT_CALL_SUPPORTED
508 static Object* Runtime_IsInPrototypeChain(Object* O, Object* V) {
509 AssertNoAllocation na;
510 #else
500 static Object* Runtime_IsInPrototypeChain(Arguments args) { 511 static Object* Runtime_IsInPrototypeChain(Arguments args) {
501 NoHandleAllocation ha; 512 NoHandleAllocation ha;
502 ASSERT(args.length() == 2); 513 ASSERT(args.length() == 2);
503 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
504 Object* O = args[0]; 514 Object* O = args[0];
505 Object* V = args[1]; 515 Object* V = args[1];
516 #endif
517 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
506 while (true) { 518 while (true) {
507 Object* prototype = V->GetPrototype(); 519 Object* prototype = V->GetPrototype();
508 if (prototype->IsNull()) return Heap::false_value(); 520 if (prototype->IsNull()) return Heap::false_value();
509 if (O == prototype) return Heap::true_value(); 521 if (O == prototype) return Heap::true_value();
510 V = prototype; 522 V = prototype;
511 } 523 }
512 } 524 }
513 525
514 526
515 // Inserts an object as the hidden prototype of another object. 527 // Inserts an object as the hidden prototype of another object.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 elms->set(1, result.GetLazyValue()); 629 elms->set(1, result.GetLazyValue());
618 elms->set(2, Heap::ToBoolean(!result.IsReadOnly())); 630 elms->set(2, Heap::ToBoolean(!result.IsReadOnly()));
619 } 631 }
620 632
621 elms->set(3, Heap::ToBoolean(!result.IsDontEnum())); 633 elms->set(3, Heap::ToBoolean(!result.IsDontEnum()));
622 elms->set(4, Heap::ToBoolean(!result.IsDontDelete())); 634 elms->set(4, Heap::ToBoolean(!result.IsDontDelete()));
623 return *desc; 635 return *desc;
624 } 636 }
625 637
626 638
639 #ifdef DIRECT_CALL_SUPPORTED
640 static Object* Runtime_IsExtensible(Object* arg) {
641 AssertNoAllocation na;
642 ASSERT(arg->IsJSObject());
643 JSObject* obj = JSObject::cast(arg);
644 #else
627 static Object* Runtime_IsExtensible(Arguments args) { 645 static Object* Runtime_IsExtensible(Arguments args) {
628 ASSERT(args.length() == 1); 646 ASSERT(args.length() == 1);
629 CONVERT_CHECKED(JSObject, obj, args[0]); 647 CONVERT_CHECKED(JSObject, obj, args[0]);
648 #endif
630 return obj->map()->is_extensible() ? Heap::true_value() 649 return obj->map()->is_extensible() ? Heap::true_value()
631 : Heap::false_value(); 650 : Heap::false_value();
632 } 651 }
633 652
634 653
635 static Object* Runtime_RegExpCompile(Arguments args) { 654 static Object* Runtime_RegExpCompile(Arguments args) {
636 HandleScope scope; 655 HandleScope scope;
637 ASSERT(args.length() == 3); 656 ASSERT(args.length() == 3);
638 CONVERT_ARG_CHECKED(JSRegExp, re, 0); 657 CONVERT_ARG_CHECKED(JSRegExp, re, 0);
639 CONVERT_ARG_CHECKED(String, pattern, 1); 658 CONVERT_ARG_CHECKED(String, pattern, 1);
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 &has_pending_exception); 1272 &has_pending_exception);
1254 if (has_pending_exception) { 1273 if (has_pending_exception) {
1255 ASSERT(Top::has_pending_exception()); 1274 ASSERT(Top::has_pending_exception());
1256 return Failure::Exception(); 1275 return Failure::Exception();
1257 } 1276 }
1258 literals->set(index, *regexp); 1277 literals->set(index, *regexp);
1259 return *regexp; 1278 return *regexp;
1260 } 1279 }
1261 1280
1262 1281
1282 #ifdef DIRECT_CALL_SUPPORTED
1283 static Object* Runtime_FunctionGetName(Object* arg) {
1284 AssertNoAllocation na;
1285
1286 ASSERT(arg->IsJSFunction());
1287 JSFunction* f = JSFunction::cast(arg);
1288 #else
1263 static Object* Runtime_FunctionGetName(Arguments args) { 1289 static Object* Runtime_FunctionGetName(Arguments args) {
1264 NoHandleAllocation ha; 1290 NoHandleAllocation ha;
1265 ASSERT(args.length() == 1); 1291 ASSERT(args.length() == 1);
1266 1292
1267 CONVERT_CHECKED(JSFunction, f, args[0]); 1293 CONVERT_CHECKED(JSFunction, f, args[0]);
1294 #endif
1268 return f->shared()->name(); 1295 return f->shared()->name();
1269 } 1296 }
1270 1297
1271 1298
1299 #ifdef DIRECT_CALL_SUPPORTED
1300 static Object* Runtime_FunctionSetName(Object* arg0, Object* arg1) {
1301 AssertNoAllocation na;
1302
1303 ASSERT(arg0->IsJSFunction());
1304 JSFunction* f = JSFunction::cast(arg0);
1305 ASSERT(arg1->IsString());
1306 String* name = String::cast(arg1);
1307 #else
1272 static Object* Runtime_FunctionSetName(Arguments args) { 1308 static Object* Runtime_FunctionSetName(Arguments args) {
1273 NoHandleAllocation ha; 1309 NoHandleAllocation ha;
1274 ASSERT(args.length() == 2); 1310 ASSERT(args.length() == 2);
1275 1311
1276 CONVERT_CHECKED(JSFunction, f, args[0]); 1312 CONVERT_CHECKED(JSFunction, f, args[0]);
1277 CONVERT_CHECKED(String, name, args[1]); 1313 CONVERT_CHECKED(String, name, args[1]);
1314 #endif
1278 f->shared()->set_name(name); 1315 f->shared()->set_name(name);
1279 return Heap::undefined_value(); 1316 return Heap::undefined_value();
1280 } 1317 }
1281 1318
1282 1319
1283 static Object* Runtime_FunctionGetScript(Arguments args) { 1320 static Object* Runtime_FunctionGetScript(Arguments args) {
1284 HandleScope scope; 1321 HandleScope scope;
1285 ASSERT(args.length() == 1); 1322 ASSERT(args.length() == 1);
1286 1323
1287 CONVERT_CHECKED(JSFunction, fun, args[0]); 1324 CONVERT_CHECKED(JSFunction, fun, args[0]);
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after
2484 break; 2521 break;
2485 } 2522 }
2486 } 2523 }
2487 if (found) return Smi::FromInt(i); 2524 if (found) return Smi::FromInt(i);
2488 } 2525 }
2489 2526
2490 return Smi::FromInt(-1); 2527 return Smi::FromInt(-1);
2491 } 2528 }
2492 2529
2493 2530
2531 #ifdef DIRECT_CALL_SUPPORTED
2532 static Object* Runtime_StringLocaleCompare(Object* arg0, Object* arg1) {
2533 AssertNoAllocation na;
2534 String* str1 = String::cast(arg0);
2535 String* str2 = String::cast(arg1);
2536 #else
2494 static Object* Runtime_StringLocaleCompare(Arguments args) { 2537 static Object* Runtime_StringLocaleCompare(Arguments args) {
2495 NoHandleAllocation ha; 2538 NoHandleAllocation ha;
2496 ASSERT(args.length() == 2); 2539 ASSERT(args.length() == 2);
2497 2540
2498 CONVERT_CHECKED(String, str1, args[0]); 2541 CONVERT_CHECKED(String, str1, args[0]);
2499 CONVERT_CHECKED(String, str2, args[1]); 2542 CONVERT_CHECKED(String, str2, args[1]);
2543 #endif
2500 2544
2501 if (str1 == str2) return Smi::FromInt(0); // Equal. 2545 if (str1 == str2) return Smi::FromInt(0); // Equal.
2502 int str1_length = str1->length(); 2546 int str1_length = str1->length();
2503 int str2_length = str2->length(); 2547 int str2_length = str2->length();
2504 2548
2505 // Decide trivial cases without flattening. 2549 // Decide trivial cases without flattening.
2506 if (str1_length == 0) { 2550 if (str1_length == 0) {
2507 if (str2_length == 0) return Smi::FromInt(0); // Equal. 2551 if (str2_length == 0) return Smi::FromInt(0); // Equal.
2508 return Smi::FromInt(-str2_length); 2552 return Smi::FromInt(-str2_length);
2509 } else { 2553 } else {
(...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after
3531 ASSERT(args.length() == 1); 3575 ASSERT(args.length() == 1);
3532 Handle<Object> object = args.at<Object>(0); 3576 Handle<Object> object = args.at<Object>(0);
3533 if (object->IsJSObject()) { 3577 if (object->IsJSObject()) {
3534 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 3578 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
3535 js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 3579 js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
3536 } 3580 }
3537 return *object; 3581 return *object;
3538 } 3582 }
3539 3583
3540 3584
3585 #ifdef DIRECT_CALL_SUPPORTED
3586 static Object* Runtime_ToBool(Object* arg) {
3587 AssertNoAllocation na;
3588
3589 return arg->ToBoolean();
3590 }
3591 #else
3541 static Object* Runtime_ToBool(Arguments args) { 3592 static Object* Runtime_ToBool(Arguments args) {
3542 NoHandleAllocation ha; 3593 NoHandleAllocation ha;
3543 ASSERT(args.length() == 1); 3594 ASSERT(args.length() == 1);
3544 3595
3545 return args[0]->ToBoolean(); 3596 return args[0]->ToBoolean();
3546 } 3597 }
3598 #endif
3547 3599
3548 3600
3549 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47). 3601 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
3550 // Possible optimizations: put the type string into the oddballs. 3602 // Possible optimizations: put the type string into the oddballs.
3603 #ifdef DIRECT_CALL_SUPPORTED
3604 static Object* Runtime_Typeof(Object* obj) {
3605 AssertNoAllocation na;
3606 #else
3551 static Object* Runtime_Typeof(Arguments args) { 3607 static Object* Runtime_Typeof(Arguments args) {
3552 NoHandleAllocation ha; 3608 NoHandleAllocation ha;
3553
3554 Object* obj = args[0]; 3609 Object* obj = args[0];
3610 #endif
3555 if (obj->IsNumber()) return Heap::number_symbol(); 3611 if (obj->IsNumber()) return Heap::number_symbol();
3556 HeapObject* heap_obj = HeapObject::cast(obj); 3612 HeapObject* heap_obj = HeapObject::cast(obj);
3557 3613
3558 // typeof an undetectable object is 'undefined' 3614 // typeof an undetectable object is 'undefined'
3559 if (heap_obj->map()->is_undetectable()) return Heap::undefined_symbol(); 3615 if (heap_obj->map()->is_undetectable()) return Heap::undefined_symbol();
3560 3616
3561 InstanceType instance_type = heap_obj->map()->instance_type(); 3617 InstanceType instance_type = heap_obj->map()->instance_type();
3562 if (instance_type < FIRST_NONSTRING_TYPE) { 3618 if (instance_type < FIRST_NONSTRING_TYPE) {
3563 return Heap::string_symbol(); 3619 return Heap::string_symbol();
3564 } 3620 }
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
4094 4150
4095 Object* obj = args[0]; 4151 Object* obj = args[0];
4096 if (obj->IsSmi()) return obj; 4152 if (obj->IsSmi()) return obj;
4097 CONVERT_DOUBLE_CHECKED(number, obj); 4153 CONVERT_DOUBLE_CHECKED(number, obj);
4098 return Heap::NumberFromInt32(DoubleToInt32(number)); 4154 return Heap::NumberFromInt32(DoubleToInt32(number));
4099 } 4155 }
4100 4156
4101 4157
4102 // Converts a Number to a Smi, if possible. Returns NaN if the number is not 4158 // Converts a Number to a Smi, if possible. Returns NaN if the number is not
4103 // a small integer. 4159 // a small integer.
4160 #ifdef DIRECT_CALL_SUPPORTED
4161 static Object* Runtime_NumberToSmi(Object* obj) {
4162 AssertNoAllocation na;
4163 #else
4104 static Object* Runtime_NumberToSmi(Arguments args) { 4164 static Object* Runtime_NumberToSmi(Arguments args) {
4105 NoHandleAllocation ha; 4165 NoHandleAllocation ha;
4106 ASSERT(args.length() == 1); 4166 ASSERT(args.length() == 1);
4107 4167
4108 Object* obj = args[0]; 4168 Object* obj = args[0];
4169 #endif
4109 if (obj->IsSmi()) { 4170 if (obj->IsSmi()) {
4110 return obj; 4171 return obj;
4111 } 4172 }
4112 if (obj->IsHeapNumber()) { 4173 if (obj->IsHeapNumber()) {
4113 double value = HeapNumber::cast(obj)->value(); 4174 double value = HeapNumber::cast(obj)->value();
4114 int int_value = FastD2I(value); 4175 int int_value = FastD2I(value);
4115 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) { 4176 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
4116 return Smi::FromInt(int_value); 4177 return Smi::FromInt(int_value);
4117 } 4178 }
4118 } 4179 }
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
4394 static Object* Runtime_NumberSar(Arguments args) { 4455 static Object* Runtime_NumberSar(Arguments args) {
4395 NoHandleAllocation ha; 4456 NoHandleAllocation ha;
4396 ASSERT(args.length() == 2); 4457 ASSERT(args.length() == 2);
4397 4458
4398 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); 4459 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
4399 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); 4460 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
4400 return Heap::NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f)); 4461 return Heap::NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f));
4401 } 4462 }
4402 4463
4403 4464
4465 #ifdef DIRECT_CALL_SUPPORTED
4466 static Object* Runtime_NumberEquals(Object* arg0, Object* arg1) {
4467 AssertNoAllocation na;
4468
4469 ASSERT(arg0->IsNumber());
4470 double x = arg0->Number();
4471 ASSERT(arg1->IsNumber());
4472 double y = arg1->Number();
4473 #else
4404 static Object* Runtime_NumberEquals(Arguments args) { 4474 static Object* Runtime_NumberEquals(Arguments args) {
4405 NoHandleAllocation ha; 4475 NoHandleAllocation ha;
4406 ASSERT(args.length() == 2); 4476 ASSERT(args.length() == 2);
4407 4477
4408 CONVERT_DOUBLE_CHECKED(x, args[0]); 4478 CONVERT_DOUBLE_CHECKED(x, args[0]);
4409 CONVERT_DOUBLE_CHECKED(y, args[1]); 4479 CONVERT_DOUBLE_CHECKED(y, args[1]);
4480 #endif
4410 if (isnan(x)) return Smi::FromInt(NOT_EQUAL); 4481 if (isnan(x)) return Smi::FromInt(NOT_EQUAL);
4411 if (isnan(y)) return Smi::FromInt(NOT_EQUAL); 4482 if (isnan(y)) return Smi::FromInt(NOT_EQUAL);
4412 if (x == y) return Smi::FromInt(EQUAL); 4483 if (x == y) return Smi::FromInt(EQUAL);
4413 Object* result; 4484 Object* result;
4414 if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) { 4485 if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
4415 result = Smi::FromInt(EQUAL); 4486 result = Smi::FromInt(EQUAL);
4416 } else { 4487 } else {
4417 result = Smi::FromInt(NOT_EQUAL); 4488 result = Smi::FromInt(NOT_EQUAL);
4418 } 4489 }
4419 return result; 4490 return result;
4420 } 4491 }
4421 4492
4422 4493
4494 #ifdef DIRECT_CALL_SUPPORTED
4495 static Object* Runtime_StringEquals(Object* arg0, Object* arg1) {
4496 AssertNoAllocation na;
4497
4498 ASSERT(arg0->IsString());
4499 String* x = String::cast(arg0);
4500 ASSERT(arg1->IsString());
4501 String* y = String::cast(arg1);
4502 #else
4423 static Object* Runtime_StringEquals(Arguments args) { 4503 static Object* Runtime_StringEquals(Arguments args) {
4424 NoHandleAllocation ha; 4504 NoHandleAllocation ha;
4425 ASSERT(args.length() == 2); 4505 ASSERT(args.length() == 2);
4426 4506
4427 CONVERT_CHECKED(String, x, args[0]); 4507 CONVERT_CHECKED(String, x, args[0]);
4428 CONVERT_CHECKED(String, y, args[1]); 4508 CONVERT_CHECKED(String, y, args[1]);
4509 #endif
4429 4510
4430 bool not_equal = !x->Equals(y); 4511 bool not_equal = !x->Equals(y);
4431 // This is slightly convoluted because the value that signifies 4512 // This is slightly convoluted because the value that signifies
4432 // equality is 0 and inequality is 1 so we have to negate the result 4513 // equality is 0 and inequality is 1 so we have to negate the result
4433 // from String::Equals. 4514 // from String::Equals.
4434 ASSERT(not_equal == 0 || not_equal == 1); 4515 ASSERT(not_equal == 0 || not_equal == 1);
4435 STATIC_CHECK(EQUAL == 0); 4516 STATIC_CHECK(EQUAL == 0);
4436 STATIC_CHECK(NOT_EQUAL == 1); 4517 STATIC_CHECK(NOT_EQUAL == 1);
4437 return Smi::FromInt(not_equal); 4518 return Smi::FromInt(not_equal);
4438 } 4519 }
4439 4520
4440 4521
4522 #ifdef DIRECT_CALL_SUPPORTED
4523 static Object* Runtime_NumberCompare(Object* arg0, Object* arg1, Object* arg2) {
4524 NoHandleAllocation ha;
4525
4526 ASSERT(arg0->IsNumber());
4527 double x = arg0->Number();
4528 ASSERT(arg1->IsNumber());
4529 double y = arg1->Number();
4530 if (isnan(x) || isnan(y)) return arg2;
4531 #else
4441 static Object* Runtime_NumberCompare(Arguments args) { 4532 static Object* Runtime_NumberCompare(Arguments args) {
4442 NoHandleAllocation ha; 4533 NoHandleAllocation ha;
4443 ASSERT(args.length() == 3); 4534 ASSERT(args.length() == 3);
4444 4535
4445 CONVERT_DOUBLE_CHECKED(x, args[0]); 4536 CONVERT_DOUBLE_CHECKED(x, args[0]);
4446 CONVERT_DOUBLE_CHECKED(y, args[1]); 4537 CONVERT_DOUBLE_CHECKED(y, args[1]);
4447 if (isnan(x) || isnan(y)) return args[2]; 4538 if (isnan(x) || isnan(y)) return args[2];
4539 #endif
4448 if (x == y) return Smi::FromInt(EQUAL); 4540 if (x == y) return Smi::FromInt(EQUAL);
4449 if (isless(x, y)) return Smi::FromInt(LESS); 4541 if (isless(x, y)) return Smi::FromInt(LESS);
4450 return Smi::FromInt(GREATER); 4542 return Smi::FromInt(GREATER);
4451 } 4543 }
4452 4544
4453 4545
4454 // Compare two Smis as if they were converted to strings and then 4546 // Compare two Smis as if they were converted to strings and then
4455 // compared lexicographically. 4547 // compared lexicographically.
4548 #ifdef DIRECT_CALL_SUPPORTED
4549 static Object* Runtime_SmiLexicographicCompare(Object* arg0, Object* arg1) {
4550 AssertNoAllocation na;
4551
4552 // Extract the integer values from the Smis.
4553 ASSERT(arg0->IsSmi());
4554 Smi* x = Smi::cast(arg0);
4555 ASSERT(arg1->IsSmi());
4556 Smi* y = Smi::cast(arg1);
4557 #else
4456 static Object* Runtime_SmiLexicographicCompare(Arguments args) { 4558 static Object* Runtime_SmiLexicographicCompare(Arguments args) {
4457 NoHandleAllocation ha; 4559 NoHandleAllocation ha;
4458 ASSERT(args.length() == 2); 4560 ASSERT(args.length() == 2);
4459 4561
4562 // Extract the integer values from the Smis.
4563 CONVERT_CHECKED(Smi, x, args[0]);
4564 CONVERT_CHECKED(Smi, y, args[1]);
4565 #endif
4566
4460 // Arrays for the individual characters of the two Smis. Smis are 4567 // Arrays for the individual characters of the two Smis. Smis are
4461 // 31 bit integers and 10 decimal digits are therefore enough. 4568 // 31 bit integers and 10 decimal digits are therefore enough.
4462 static int x_elms[10]; 4569 static int x_elms[10];
4463 static int y_elms[10]; 4570 static int y_elms[10];
4464 4571
4465 // Extract the integer values from the Smis.
4466 CONVERT_CHECKED(Smi, x, args[0]);
4467 CONVERT_CHECKED(Smi, y, args[1]);
4468 int x_value = x->value(); 4572 int x_value = x->value();
4469 int y_value = y->value(); 4573 int y_value = y->value();
4470 4574
4471 // If the integers are equal so are the string representations. 4575 // If the integers are equal so are the string representations.
4472 if (x_value == y_value) return Smi::FromInt(EQUAL); 4576 if (x_value == y_value) return Smi::FromInt(EQUAL);
4473 4577
4474 // If one of the integers are zero the normal integer order is the 4578 // If one of the integers are zero the normal integer order is the
4475 // same as the lexicographic order of the string representations. 4579 // same as the lexicographic order of the string representations.
4476 if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value); 4580 if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value);
4477 4581
(...skipping 26 matching lines...) Expand all
4504 if (diff != 0) return Smi::FromInt(diff); 4608 if (diff != 0) return Smi::FromInt(diff);
4505 } 4609 }
4506 4610
4507 // If one array is a suffix of the other array, the longest array is 4611 // If one array is a suffix of the other array, the longest array is
4508 // the representation of the largest of the Smis in the 4612 // the representation of the largest of the Smis in the
4509 // lexicographic ordering. 4613 // lexicographic ordering.
4510 return Smi::FromInt(x_index - y_index); 4614 return Smi::FromInt(x_index - y_index);
4511 } 4615 }
4512 4616
4513 4617
4618 #ifdef DIRECT_CALL_SUPPORTED
4619 static Object* Runtime_StringCompare(Object* arg0, Object* arg1) {
4620 AssertNoAllocation na;
4621
4622 ASSERT(arg0->IsString());
4623 String* x = String::cast(arg0);
4624 ASSERT(arg1->IsString());
4625 String* y = String::cast(arg1);
4626 #else
4514 static Object* Runtime_StringCompare(Arguments args) { 4627 static Object* Runtime_StringCompare(Arguments args) {
4515 NoHandleAllocation ha; 4628 NoHandleAllocation ha;
4516 ASSERT(args.length() == 2); 4629 ASSERT(args.length() == 2);
4517 4630
4518 CONVERT_CHECKED(String, x, args[0]); 4631 CONVERT_CHECKED(String, x, args[0]);
4519 CONVERT_CHECKED(String, y, args[1]); 4632 CONVERT_CHECKED(String, y, args[1]);
4633 #endif
4520 4634
4521 Counters::string_compare_runtime.Increment(); 4635 Counters::string_compare_runtime.Increment();
4522 4636
4523 // A few fast case tests before we flatten. 4637 // A few fast case tests before we flatten.
4524 if (x == y) return Smi::FromInt(EQUAL); 4638 if (x == y) return Smi::FromInt(EQUAL);
4525 if (y->length() == 0) { 4639 if (y->length() == 0) {
4526 if (x->length() == 0) return Smi::FromInt(EQUAL); 4640 if (x->length() == 0) return Smi::FromInt(EQUAL);
4527 return Smi::FromInt(GREATER); 4641 return Smi::FromInt(GREATER);
4528 } else if (x->length() == 0) { 4642 } else if (x->length() == 0) {
4529 return Smi::FromInt(LESS); 4643 return Smi::FromInt(LESS);
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after
5450 5564
5451 static Object* Runtime_DateDaylightSavingsOffset(Arguments args) { 5565 static Object* Runtime_DateDaylightSavingsOffset(Arguments args) {
5452 NoHandleAllocation ha; 5566 NoHandleAllocation ha;
5453 ASSERT(args.length() == 1); 5567 ASSERT(args.length() == 1);
5454 5568
5455 CONVERT_DOUBLE_CHECKED(x, args[0]); 5569 CONVERT_DOUBLE_CHECKED(x, args[0]);
5456 return Heap::NumberFromDouble(OS::DaylightSavingsOffset(x)); 5570 return Heap::NumberFromDouble(OS::DaylightSavingsOffset(x));
5457 } 5571 }
5458 5572
5459 5573
5574 #ifdef DIRECT_CALL_SUPPORTED
5575 static Object* Runtime_NumberIsFinite(Object* arg0) {
5576 AssertNoAllocation na;
5577 ASSERT(arg0->IsNumber());
5578 double value = arg0->Number();
5579 #else
5460 static Object* Runtime_NumberIsFinite(Arguments args) { 5580 static Object* Runtime_NumberIsFinite(Arguments args) {
5461 NoHandleAllocation ha; 5581 NoHandleAllocation ha;
5462 ASSERT(args.length() == 1); 5582 ASSERT(args.length() == 1);
5463 5583
5464 CONVERT_DOUBLE_CHECKED(value, args[0]); 5584 CONVERT_DOUBLE_CHECKED(value, args[0]);
5585 #endif
5465 Object* result; 5586 Object* result;
5466 if (isnan(value) || (fpclassify(value) == FP_INFINITE)) { 5587 if (isnan(value) || (fpclassify(value) == FP_INFINITE)) {
5467 result = Heap::false_value(); 5588 result = Heap::false_value();
5468 } else { 5589 } else {
5469 result = Heap::true_value(); 5590 result = Heap::true_value();
5470 } 5591 }
5471 return result; 5592 return result;
5472 } 5593 }
5473 5594
5474 5595
(...skipping 2627 matching lines...) Expand 10 before | Expand all | Expand 10 after
8102 8223
8103 #ifdef DEBUG 8224 #ifdef DEBUG
8104 // ListNatives is ONLY used by the fuzz-natives.js in debug mode 8225 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
8105 // Exclude the code in release mode. 8226 // Exclude the code in release mode.
8106 static Object* Runtime_ListNatives(Arguments args) { 8227 static Object* Runtime_ListNatives(Arguments args) {
8107 ASSERT(args.length() == 0); 8228 ASSERT(args.length() == 0);
8108 HandleScope scope; 8229 HandleScope scope;
8109 Handle<JSArray> result = Factory::NewJSArray(0); 8230 Handle<JSArray> result = Factory::NewJSArray(0);
8110 int index = 0; 8231 int index = 0;
8111 #define ADD_ENTRY(Name, argc, ressize) \ 8232 #define ADD_ENTRY(Name, argc, ressize) \
8112 { \ 8233 if (Runtime::FunctionForId(Runtime::k##Name)->calling_convention != \
8234 Runtime::DIRECT_CALL_NOT_FAILS) { \
8113 HandleScope inner; \ 8235 HandleScope inner; \
8114 Handle<String> name = \ 8236 Handle<String> name = \
8115 Factory::NewStringFromAscii( \ 8237 Factory::NewStringFromAscii( \
8116 Vector<const char>(#Name, StrLength(#Name))); \ 8238 Vector<const char>(#Name, StrLength(#Name))); \
8117 Handle<JSArray> pair = Factory::NewJSArray(0); \ 8239 Handle<JSArray> pair = Factory::NewJSArray(0); \
8118 SetElement(pair, 0, name); \ 8240 SetElement(pair, 0, name); \
8119 SetElement(pair, 1, Handle<Smi>(Smi::FromInt(argc))); \ 8241 SetElement(pair, 1, Handle<Smi>(Smi::FromInt(argc))); \
8120 SetElement(result, index++, pair); \ 8242 SetElement(result, index++, pair); \
8121 } 8243 }
8122 RUNTIME_FUNCTION_LIST(ADD_ENTRY) 8244 RUNTIME_FUNCTION_LIST(ADD_ENTRY)
(...skipping 11 matching lines...) Expand all
8134 Logger::LogRuntime(chars, elms); 8256 Logger::LogRuntime(chars, elms);
8135 return Heap::undefined_value(); 8257 return Heap::undefined_value();
8136 } 8258 }
8137 8259
8138 8260
8139 static Object* Runtime_IS_VAR(Arguments args) { 8261 static Object* Runtime_IS_VAR(Arguments args) {
8140 UNREACHABLE(); // implemented as macro in the parser 8262 UNREACHABLE(); // implemented as macro in the parser
8141 return NULL; 8263 return NULL;
8142 } 8264 }
8143 8265
8266 // ----------------------------------------------------------------------------
8267 // Utilities for building the runtime function list
8268 namespace {
8269
8270 template <size_t kId>
8271 class SignatureTag {
8272 char a[kId]; // there is a biection between id and sizeof(SignatureTag<kId>)
8273 };
8274
8275
8276 template <size_t signature_tag_size> struct FunctionTraits;
8277
8278
8279 #define SIGNATURE_TRAITS(id, signature) \
8280 SignatureTag<id> GetTag(signature); \
8281 template <> struct FunctionTraits<sizeof(SignatureTag<id>)>
8282
8283 SIGNATURE_TRAITS(1, Object* (*)(Arguments)) {
8284 static const Runtime::CallingConvention conv = Runtime::EXIT_FRAME_CALL;
8285 };
8286
8287
8288 SIGNATURE_TRAITS(2, ObjectPair (*)(Arguments)) {
8289 static const Runtime::CallingConvention conv = Runtime::EXIT_FRAME_CALL;
8290 };
8291
8292
8293 SIGNATURE_TRAITS(3, Object* (*)(Object* arg)) {
8294 static const Runtime::CallingConvention conv = Runtime::DIRECT_CALL_NOT_FAILS;
8295 };
8296
8297
8298 SIGNATURE_TRAITS(4, Object* (*)(Object* agr0, Object* arg1)) {
8299 static const Runtime::CallingConvention conv = Runtime::DIRECT_CALL_NOT_FAILS;
8300 };
8301
8302 SIGNATURE_TRAITS(5, Object* (*)(Object* arg0, Object* arg1, Object* arg2)) {
8303 static const Runtime::CallingConvention conv = Runtime::DIRECT_CALL_NOT_FAILS;
8304 };
8305 }
8144 8306
8145 // ---------------------------------------------------------------------------- 8307 // ----------------------------------------------------------------------------
8146 // Implementation of Runtime 8308 // Implementation of Runtime
8147 8309
8148 #define F(name, nargs, ressize) \ 8310 #define F(name, nargs, ressize) \
8149 { #name, FUNCTION_ADDR(Runtime_##name), nargs, \ 8311 { #name, FUNCTION_ADDR(Runtime_##name), nargs, \
8150 static_cast<int>(Runtime::k##name), ressize }, 8312 static_cast<int>(Runtime::k##name), ressize, \
8313 FunctionTraits<sizeof(GetTag(Runtime_##name))>::conv},
8151 8314
8152 static Runtime::Function Runtime_functions[] = { 8315 static Runtime::Function Runtime_functions[] = {
8153 RUNTIME_FUNCTION_LIST(F) 8316 RUNTIME_FUNCTION_LIST(F)
8154 { NULL, NULL, 0, -1, 0 } 8317 { NULL, NULL, 0, -1, 0, Runtime::EXIT_FRAME_CALL }
8155 }; 8318 };
8156 8319
8157 #undef F 8320 #undef F
8158 8321
8159 8322
8160 Runtime::Function* Runtime::FunctionForId(FunctionId fid) { 8323 Runtime::Function* Runtime::FunctionForId(FunctionId fid) {
8161 ASSERT(0 <= fid && fid < kNofFunctions); 8324 ASSERT(0 <= fid && fid < kNofFunctions);
8162 return &Runtime_functions[fid]; 8325 return &Runtime_functions[fid];
8163 } 8326 }
8164 8327
(...skipping 17 matching lines...) Expand all
8182 } else { 8345 } else {
8183 // Handle last resort GC and make sure to allow future allocations 8346 // Handle last resort GC and make sure to allow future allocations
8184 // to grow the heap without causing GCs (if possible). 8347 // to grow the heap without causing GCs (if possible).
8185 Counters::gc_last_resort_from_js.Increment(); 8348 Counters::gc_last_resort_from_js.Increment();
8186 Heap::CollectAllGarbage(false); 8349 Heap::CollectAllGarbage(false);
8187 } 8350 }
8188 } 8351 }
8189 8352
8190 8353
8191 } } // namespace v8::internal 8354 } } // namespace v8::internal
OLDNEW
« src/runtime.h ('K') | « src/runtime.h ('k') | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698