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

Side by Side Diff: src/hydrogen-instructions.cc

Issue 10544196: Defer creating Handles for HConstants to the code generation phase. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase & cosmetic changes. Created 8 years, 5 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 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 981 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 992
993 993
994 HValue* HCheckInstanceType::Canonicalize() { 994 HValue* HCheckInstanceType::Canonicalize() {
995 if (check_ == IS_STRING && 995 if (check_ == IS_STRING &&
996 !value()->type().IsUninitialized() && 996 !value()->type().IsUninitialized() &&
997 value()->type().IsString()) { 997 value()->type().IsString()) {
998 return NULL; 998 return NULL;
999 } 999 }
1000 if (check_ == IS_SYMBOL && 1000 if (check_ == IS_SYMBOL &&
1001 value()->IsConstant() && 1001 value()->IsConstant() &&
1002 HConstant::cast(value())->handle()->IsSymbol()) { 1002 HConstant::cast(value())->IsSymbol()) {
1003 return NULL; 1003 return NULL;
1004 } 1004 }
1005 return this; 1005 return this;
1006 } 1006 }
1007 1007
1008 1008
1009 void HCheckInstanceType::GetCheckInterval(InstanceType* first, 1009 void HCheckInstanceType::GetCheckInterval(InstanceType* first,
1010 InstanceType* last) { 1010 InstanceType* last) {
1011 ASSERT(is_interval_check()); 1011 ASSERT(is_interval_check());
1012 switch (check_) { 1012 switch (check_) {
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 void HEnterInlined::PrintDataTo(StringStream* stream) { 1377 void HEnterInlined::PrintDataTo(StringStream* stream) {
1378 SmartArrayPointer<char> name = function()->debug_name()->ToCString(); 1378 SmartArrayPointer<char> name = function()->debug_name()->ToCString();
1379 stream->Add("%s, id=%d", *name, function()->id()); 1379 stream->Add("%s, id=%d", *name, function()->id());
1380 } 1380 }
1381 1381
1382 1382
1383 HConstant::HConstant(Handle<Object> handle, Representation r) 1383 HConstant::HConstant(Handle<Object> handle, Representation r)
1384 : handle_(handle), 1384 : handle_(handle),
1385 has_int32_value_(false), 1385 has_int32_value_(false),
1386 has_double_value_(false), 1386 has_double_value_(false),
1387 int32_value_(0), 1387 handle_was_smi_(handle->IsSmi()),
1388 double_value_(0) { 1388 is_string_(false),
1389 is_symbol_(false),
1390 is_boolean_(false) {
1389 set_representation(r); 1391 set_representation(r);
1390 SetFlag(kUseGVN); 1392 SetFlag(kUseGVN);
1391 if (handle_->IsNumber()) { 1393
1394 // We try to use the fact that we've already checked if the handle
1395 // is a Smi.
1396 if (handle_was_smi_) {
1397 has_int32_value_ = true;
1398 has_double_value_ = true;
1399 int32_value_ = Smi::cast(*handle)->value();
1400 double_value_ = FastI2D(int32_value_);
1401 } else if (handle_->IsHeapNumber()) {
1392 double n = handle_->Number(); 1402 double n = handle_->Number();
1393 double roundtrip_value = static_cast<double>(static_cast<int32_t>(n)); 1403 double roundtrip_value = static_cast<double>(static_cast<int32_t>(n));
1394 has_int32_value_ = BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(n); 1404 has_int32_value_ = BitCast<int64_t>(roundtrip_value) ==
1395 if (has_int32_value_) int32_value_ = static_cast<int32_t>(n); 1405 BitCast<int64_t>(n);
1406
1407 int32_value_ = DoubleToInt32(n);
1396 double_value_ = n; 1408 double_value_ = n;
1397 has_double_value_ = true; 1409 has_double_value_ = true;
1410 } else {
1411 is_string_ = handle->IsString();
1412 is_symbol_ = !is_string_ && handle->IsSymbol();
1413 is_boolean_ = !is_symbol_ && !is_string_ && handle->IsBoolean();
1414 }
1415 }
1416
1417
1418 HConstant::HConstant(int32_t integer_value, Representation r,
1419 Handle<Object> handle)
1420 : handle_(handle),
1421 has_int32_value_(true),
1422 has_double_value_(true),
1423 is_string_(false),
1424 is_symbol_(false),
1425 is_boolean_(false) {
1426 set_representation(r);
1427 SetFlag(kUseGVN);
1428 int32_value_ = integer_value;
1429 double_value_ = FastI2D(integer_value);
1430 if (handle.is_null()) {
1431 // If we can safely represent this integer in 31 bits and we don't
1432 // have a Handle to the HeapObject, we pretend it originated from
1433 // a Smi. This is okay because when we _do_ create a HeapObject
1434 // for this HConstant, it will be a Smi.
1435 handle_was_smi_ = Smi::IsValid(static_cast<intptr_t>(integer_value));
1436 } else {
1437 handle_was_smi_ = handle->IsSmi();
1438 }
1439 }
1440
1441
1442 HConstant::HConstant(double double_value, Representation r,
1443 Handle<Object> handle)
1444 : handle_(handle),
1445 has_int32_value_(false),
1446 has_double_value_(true),
1447 handle_was_smi_(false),
1448 is_string_(false),
1449 is_symbol_(false),
1450 is_boolean_(false),
1451 int32_value_(DoubleToInt32(double_value)),
1452 double_value_(double_value) {
1453 set_representation(r);
1454 SetFlag(kUseGVN);
1455 double roundtrip_value = static_cast<double>(
1456 static_cast<int32_t>(double_value));
1457 has_int32_value_ = BitCast<int64_t>(roundtrip_value) ==
1458 BitCast<int64_t>(double_value);
1459 if (handle.is_null()) {
1460 handle_was_smi_ = has_int32_value_ && Smi::IsValid(static_cast<intptr_t>(
1461 int32_value_));
1462 } else {
1463 handle_was_smi_ = handle->IsSmi();
1464 }
1465 }
1466
1467
1468 void HConstant::EnsureHasHandle(Factory* factory) {
1469 if (handle_.is_null()) {
1470 ASSERT(has_int32_value_ || has_double_value_);
1471 if (has_int32_value_) {
1472 handle_ = factory->NewNumberFromInt(int32_value_, TENURED);
1473 ASSERT(handle_->IsSmi() || !handle_was_smi_);
1474 } else {
1475 handle_ = factory->NewNumber(double_value_, TENURED);
1476 }
1398 } 1477 }
1399 } 1478 }
1400 1479
1401 1480
1402 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { 1481 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
1403 if (r.IsInteger32() && !has_int32_value_) return NULL; 1482 if (has_int32_value_) {
1404 if (r.IsDouble() && !has_double_value_) return NULL; 1483 return new(zone) HConstant(int32_value_, r, handle_);
1405 return new(zone) HConstant(handle_, r); 1484 } else if (has_double_value_) {
1485 // A double can be safely converted only to a HeapNumber. If it
1486 // was possible to store this double as a integer, we'd have done
1487 // that and has_int32_value_ would be true.
1488 if (r.IsInteger32()) {
1489 return NULL;
1490 } else {
1491 return new(zone) HConstant(double_value_, r, handle_);
1492 }
1493 } else {
1494 // A generic tagged value cannot be safely converted to any other
1495 // representation.
1496 if (r.IsTagged()) {
1497 return new(zone) HConstant(handle_, r);
1498 } else {
1499 return NULL;
1500 }
1501 }
1406 } 1502 }
1407 1503
1408 1504
1409 HConstant* HConstant::CopyToTruncatedInt32(Zone* zone) const { 1505 HConstant* HConstant::CopyToTruncatedInt32(Zone* zone) const {
1410 if (!has_double_value_) return NULL; 1506 if (has_int32_value_) {
1411 int32_t truncated = NumberToInt32(*handle_); 1507 return new(zone) HConstant(int32_value_, Representation::Integer32(),
1412 return new(zone) HConstant(FACTORY->NewNumberFromInt(truncated), 1508 handle_);
1413 Representation::Integer32()); 1509 } else if (has_double_value_) {
1510 return new(zone) HConstant(DoubleToInt32(double_value_),
1511 Representation::Integer32(),
1512 Handle<Object>::null());
1513 } else {
1514 return NULL;
1515 }
1414 } 1516 }
1415 1517
1416 1518
1417 bool HConstant::ToBoolean() const { 1519 bool HConstant::ToBoolean() const {
1418 // Converts the constant's boolean value according to 1520 // Converts the constant's boolean value according to
1419 // ECMAScript section 9.2 ToBoolean conversion. 1521 // ECMAScript section 9.2 ToBoolean conversion.
1420 if (HasInteger32Value()) return Integer32Value() != 0; 1522 if (HasInteger32Value()) return Integer32Value() != 0;
1421 if (HasDoubleValue()) { 1523 if (HasDoubleValue()) {
1422 double v = DoubleValue(); 1524 double v = DoubleValue();
1423 return v != 0 && !isnan(v); 1525 return v != 0 && !isnan(v);
1424 } 1526 }
1425 if (handle()->IsTrue()) return true; 1527 if (handle()->IsTrue()) return true;
1426 if (handle()->IsFalse()) return false; 1528 if (handle()->IsFalse()) return false;
1427 if (handle()->IsUndefined()) return false; 1529 if (handle()->IsUndefined()) return false;
1428 if (handle()->IsNull()) return false; 1530 if (handle()->IsNull()) return false;
1429 if (handle()->IsString() && 1531 if (handle()->IsString() &&
1430 String::cast(*handle())->length() == 0) return false; 1532 String::cast(*handle())->length() == 0) return false;
1431 return true; 1533 return true;
1432 } 1534 }
1433 1535
1434 void HConstant::PrintDataTo(StringStream* stream) { 1536 void HConstant::PrintDataTo(StringStream* stream) {
1435 handle()->ShortPrint(stream); 1537 if (has_int32_value_) {
1538 stream->Add("%d ", int32_value_);
1539 } else if (has_double_value_) {
1540 stream->Add("%lf ", double_value_);
1541 } else {
1542 handle()->ShortPrint(stream);
1543 }
1436 } 1544 }
1437 1545
1438 1546
1439 bool HArrayLiteral::IsCopyOnWrite() const { 1547 bool HArrayLiteral::IsCopyOnWrite() const {
1440 if (!boilerplate_object_->IsJSObject()) return false; 1548 if (!boilerplate_object_->IsJSObject()) return false;
1441 return Handle<JSObject>::cast(boilerplate_object_)->elements()->map() == 1549 return Handle<JSObject>::cast(boilerplate_object_)->elements()->map() ==
1442 HEAP->fixed_cow_array_map(); 1550 HEAP->fixed_cow_array_map();
1443 } 1551 }
1444 1552
1445 1553
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
2070 HType result = HType::Uninitialized(); 2178 HType result = HType::Uninitialized();
2071 for (int i = 0; i < OperandCount(); ++i) { 2179 for (int i = 0; i < OperandCount(); ++i) {
2072 HType current = OperandAt(i)->type(); 2180 HType current = OperandAt(i)->type();
2073 result = result.Combine(current); 2181 result = result.Combine(current);
2074 } 2182 }
2075 return result; 2183 return result;
2076 } 2184 }
2077 2185
2078 2186
2079 HType HConstant::CalculateInferredType() { 2187 HType HConstant::CalculateInferredType() {
2080 return HType::TypeFromValue(handle_); 2188 if (handle_was_smi_) return HType::Smi();
2189 if (has_int32_value_ || has_double_value_) return HType::HeapNumber();
2190 return HType::TypeFromValue(Handle<Object>(handle_));
2081 } 2191 }
2082 2192
2083 2193
2084 HType HCompareGeneric::CalculateInferredType() { 2194 HType HCompareGeneric::CalculateInferredType() {
2085 return HType::Boolean(); 2195 return HType::Boolean();
2086 } 2196 }
2087 2197
2088 2198
2089 HType HInstanceOf::CalculateInferredType() { 2199 HType HInstanceOf::CalculateInferredType() {
2090 return HType::Boolean(); 2200 return HType::Boolean();
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
2266 // If value was loaded from unboxed double backing store or 2376 // If value was loaded from unboxed double backing store or
2267 // converted from an integer then we don't have to canonicalize it. 2377 // converted from an integer then we don't have to canonicalize it.
2268 if (value()->IsLoadKeyedFastDoubleElement() || 2378 if (value()->IsLoadKeyedFastDoubleElement() ||
2269 (value()->IsChange() && HChange::cast(value())->from().IsInteger32())) { 2379 (value()->IsChange() && HChange::cast(value())->from().IsInteger32())) {
2270 return false; 2380 return false;
2271 } 2381 }
2272 return true; 2382 return true;
2273 } 2383 }
2274 2384
2275 2385
2276 #define H_CONSTANT_INT32(val) \ 2386 #define H_CONSTANT_INT32(val) \
2277 new(zone) HConstant(FACTORY->NewNumberFromInt(val, TENURED), \ 2387 new(zone) HConstant(static_cast<int32_t>(val), \
2278 Representation::Integer32()) 2388 Representation::Integer32(), \
2389 Handle<Object>::null())
2390
2279 #define H_CONSTANT_DOUBLE(val) \ 2391 #define H_CONSTANT_DOUBLE(val) \
2280 new(zone) HConstant(FACTORY->NewNumber(val, TENURED), \ 2392 new(zone) HConstant(val, Representation::Double(), Handle<Object>::null())
2281 Representation::Double())
2282 2393
2283 #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \ 2394 #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \
2284 HInstruction* HInstr::New##HInstr(Zone* zone, \ 2395 HInstruction* HInstr::New##HInstr(Zone* zone, \
2285 HValue* context, \ 2396 HValue* context, \
2286 HValue* left, \ 2397 HValue* left, \
2287 HValue* right) { \ 2398 HValue* right) { \
2288 if (left->IsConstant() && right->IsConstant()) { \ 2399 if (left->IsConstant() && right->IsConstant()) { \
2289 HConstant* c_left = HConstant::cast(left); \ 2400 HConstant* c_left = HConstant::cast(left); \
2290 HConstant* c_right = HConstant::cast(right); \ 2401 HConstant* c_right = HConstant::cast(right); \
2291 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ 2402 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
2528 2639
2529 2640
2530 void HCheckPrototypeMaps::Verify() { 2641 void HCheckPrototypeMaps::Verify() {
2531 HInstruction::Verify(); 2642 HInstruction::Verify();
2532 ASSERT(HasNoUses()); 2643 ASSERT(HasNoUses());
2533 } 2644 }
2534 2645
2535 #endif 2646 #endif
2536 2647
2537 } } // namespace v8::internal 2648 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698