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

Side by Side Diff: src/compiler/representation-change.cc

Issue 2258073002: [Turbofan]: Use new MachineTypes in access-builder. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixed write barrier issue. Created 4 years, 4 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/representation-change.h" 5 #include "src/compiler/representation-change.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 // Both are words less than or equal to 32-bits. 135 // Both are words less than or equal to 32-bits.
136 // Since loads of integers from memory implicitly sign or zero extend the 136 // Since loads of integers from memory implicitly sign or zero extend the
137 // value to the full machine word size and stores implicitly truncate, 137 // value to the full machine word size and stores implicitly truncate,
138 // no representation change is necessary. 138 // no representation change is necessary.
139 return node; 139 return node;
140 } 140 }
141 } 141 }
142 142
143 switch (use_info.representation()) { 143 switch (use_info.representation()) {
144 case MachineRepresentation::kTaggedSigned: 144 case MachineRepresentation::kTaggedSigned:
145 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
146 return GetTaggedSignedRepresentationFor(node, output_rep, output_type);
145 case MachineRepresentation::kTaggedPointer: 147 case MachineRepresentation::kTaggedPointer:
148 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
149 return GetTaggedPointerRepresentationFor(node, output_rep, output_type);
146 case MachineRepresentation::kTagged: 150 case MachineRepresentation::kTagged:
147 DCHECK(use_info.type_check() == TypeCheckKind::kNone); 151 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
148 return GetTaggedRepresentationFor(node, output_rep, output_type); 152 return GetTaggedRepresentationFor(node, output_rep, output_type);
149 case MachineRepresentation::kFloat32: 153 case MachineRepresentation::kFloat32:
150 DCHECK(use_info.type_check() == TypeCheckKind::kNone); 154 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
151 return GetFloat32RepresentationFor(node, output_rep, output_type, 155 return GetFloat32RepresentationFor(node, output_rep, output_type,
152 use_info.truncation()); 156 use_info.truncation());
153 case MachineRepresentation::kFloat64: 157 case MachineRepresentation::kFloat64:
154 return GetFloat64RepresentationFor(node, output_rep, output_type, 158 return GetFloat64RepresentationFor(node, output_rep, output_type,
155 use_node, use_info); 159 use_node, use_info);
(...skipping 11 matching lines...) Expand all
167 case MachineRepresentation::kSimd128: // Fall through. 171 case MachineRepresentation::kSimd128: // Fall through.
168 // TODO(bbudge) Handle conversions between tagged and untagged. 172 // TODO(bbudge) Handle conversions between tagged and untagged.
169 break; 173 break;
170 case MachineRepresentation::kNone: 174 case MachineRepresentation::kNone:
171 return node; 175 return node;
172 } 176 }
173 UNREACHABLE(); 177 UNREACHABLE();
174 return nullptr; 178 return nullptr;
175 } 179 }
176 180
181 Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
182 Node* node, MachineRepresentation output_rep, Type* output_type) {
183 // Eagerly fold representation changes for constants.
184 switch (node->opcode()) {
185 case IrOpcode::kNumberConstant: {
186 int32_t value = OpParameter<int32_t>(node);
187 if (Smi::IsValid(value)) {
188 return jsgraph()->Constant(value);
189 }
190 return TypeError(node, output_rep, output_type,
191 MachineRepresentation::kTaggedSigned);
192 }
193 case IrOpcode::kHeapConstant:
194 return TypeError(node, output_rep, output_type,
195 MachineRepresentation::kTaggedSigned);
196 case IrOpcode::kInt32Constant:
197 if (output_type->Is(Type::SignedSmall())) {
198 int32_t value = OpParameter<int32_t>(node);
199 return jsgraph()->Constant(value);
200 } else if (output_type->Is(Type::Unsigned32())) {
201 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
202 if (Smi::IsValid(value)) {
203 return jsgraph()->Constant(static_cast<double>(value));
Jarin 2016/08/25 05:52:05 Actually, do we ever get here? I would think that
mvstanton 2016/08/29 12:02:10 Done.
204 } else {
205 return TypeError(node, output_rep, output_type,
206 MachineRepresentation::kTaggedSigned);
207 }
208 } else {
209 return TypeError(node, output_rep, output_type,
210 MachineRepresentation::kTaggedSigned);
211 }
212 case IrOpcode::kFloat64Constant:
213 case IrOpcode::kFloat32Constant:
214 return TypeError(node, output_rep, output_type,
215 MachineRepresentation::kTaggedSigned);
216 default:
217 break;
218 }
219 // Select the correct X -> Tagged operator.
220 const Operator* op;
221 if (output_rep == MachineRepresentation::kNone) {
222 // We should only asisgn this representation if the type is empty.
223 CHECK(!output_type->IsInhabited());
224 // consider producing a smi 0 here instead of all the impossible to whatever
225 // boilerplate.
226 op = machine()->ImpossibleToTaggedSigned();
227 } else if (IsWord(output_rep)) {
228 if (output_type->Is(Type::Signed31())) {
229 op = simplified()->ChangeInt31ToTaggedSigned();
230 } else if (machine()->Is64() && output_type->Is(Type::Signed32())) {
231 op = simplified()->ChangeInt32ToTagged();
232 } else {
233 return TypeError(node, output_rep, output_type,
234 MachineRepresentation::kTaggedSigned);
235 }
236 } else {
237 return TypeError(node, output_rep, output_type,
238 MachineRepresentation::kTaggedSigned);
239 }
240 return jsgraph()->graph()->NewNode(op, node);
241 }
242
243 Node* RepresentationChanger::GetTaggedPointerRepresentationFor(
244 Node* node, MachineRepresentation output_rep, Type* output_type) {
245 // Eagerly fold representation changes for constants.
246 switch (node->opcode()) {
247 case IrOpcode::kHeapConstant:
248 return node; // No change necessary.
249 case IrOpcode::kInt32Constant:
250 if (output_type->Is(Type::Boolean())) {
251 return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant()
252 : jsgraph()->TrueConstant();
253 } else {
254 return TypeError(node, output_rep, output_type,
255 MachineRepresentation::kTaggedPointer);
256 }
257 case IrOpcode::kFloat64Constant:
258 return jsgraph()->Constant(OpParameter<double>(node));
Jarin 2016/08/25 05:52:05 I do not think this guarantees non-smi. Can't we j
mvstanton 2016/08/29 12:02:10 Good point, this and kFloat32Constant now would pr
259 case IrOpcode::kFloat32Constant:
260 return jsgraph()->Constant(OpParameter<float>(node));
261 default:
262 break;
263 }
264 if (output_rep == MachineRepresentation::kTagged) {
Jarin 2016/08/25 05:52:05 Out of curiosity, do we ever get here?
mvstanton 2016/08/29 12:02:10 Nope, I've removed it, thanks for the general thru
265 // It's a no-op as long as the output_type is not in smi range.
266 // True, we could convert the smi to a heap number, but let's be
267 // conservative.
268 if (output_type->Maybe(Type::SignedSmall())) {
269 return TypeError(node, output_rep, output_type,
270 MachineRepresentation::kTaggedPointer);
271 }
272 return node;
273 }
274 // Select the correct X -> Tagged operator.
275 const Operator* op;
276 if (output_rep == MachineRepresentation::kNone) {
277 // We should only asisgn this representation if the type is empty.
278 CHECK(!output_type->IsInhabited());
279 op = machine()->ImpossibleToTaggedPointer();
280 } else if (output_rep == MachineRepresentation::kBit) {
Jarin 2016/08/25 05:52:05 Do we ever get here?
mvstanton 2016/08/29 12:02:10 No, I've removed the case.
281 if (output_type->Is(Type::Boolean())) {
282 op = simplified()->ChangeBitToTagged();
283 } else {
284 return TypeError(node, output_rep, output_type,
285 MachineRepresentation::kTaggedPointer);
286 }
287 } else if (IsWord(output_rep)) {
288 // These are all about optimizing to smi types, and we want a pointer.
289 // Let's be very conservative at first here and declare this to be a
290 // type error.
291 return TypeError(node, output_rep, output_type,
292 MachineRepresentation::kTaggedPointer);
293 } else {
294 // TODO(mvstanton): Consider introducing a ChangeFloat64ToTaggedPointer
295 // operator, but for now all kFloat to kTaggedPointer conversions seem
296 // suspicious. Really, if we want a TaggedPointer representation we
297 // should have come from a TaggedPointer type.
298 return TypeError(node, output_rep, output_type,
299 MachineRepresentation::kTaggedPointer);
300 }
301 return jsgraph()->graph()->NewNode(op, node);
302 }
303
177 Node* RepresentationChanger::GetTaggedRepresentationFor( 304 Node* RepresentationChanger::GetTaggedRepresentationFor(
178 Node* node, MachineRepresentation output_rep, Type* output_type) { 305 Node* node, MachineRepresentation output_rep, Type* output_type) {
179 // Eagerly fold representation changes for constants. 306 // Eagerly fold representation changes for constants.
180 switch (node->opcode()) { 307 switch (node->opcode()) {
181 case IrOpcode::kNumberConstant: 308 case IrOpcode::kNumberConstant:
182 case IrOpcode::kHeapConstant: 309 case IrOpcode::kHeapConstant:
183 return node; // No change necessary. 310 return node; // No change necessary.
184 case IrOpcode::kInt32Constant: 311 case IrOpcode::kInt32Constant:
185 if (output_type->Is(Type::Signed32())) { 312 if (output_type->Is(Type::Signed32())) {
186 int32_t value = OpParameter<int32_t>(node); 313 int32_t value = OpParameter<int32_t>(node);
187 return jsgraph()->Constant(value); 314 return jsgraph()->Constant(value);
188 } else if (output_type->Is(Type::Unsigned32())) { 315 } else if (output_type->Is(Type::Unsigned32())) {
189 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); 316 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
190 return jsgraph()->Constant(static_cast<double>(value)); 317 return jsgraph()->Constant(static_cast<double>(value));
191 } else if (output_type->Is(Type::Boolean())) { 318 } else if (output_type->Is(Type::Boolean())) {
192 return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant() 319 return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant()
193 : jsgraph()->TrueConstant(); 320 : jsgraph()->TrueConstant();
194 } else { 321 } else {
195 return TypeError(node, output_rep, output_type, 322 return TypeError(node, output_rep, output_type,
196 MachineRepresentation::kTagged); 323 MachineRepresentation::kTagged);
197 } 324 }
198 case IrOpcode::kFloat64Constant: 325 case IrOpcode::kFloat64Constant:
199 return jsgraph()->Constant(OpParameter<double>(node)); 326 return jsgraph()->Constant(OpParameter<double>(node));
200 case IrOpcode::kFloat32Constant: 327 case IrOpcode::kFloat32Constant:
201 return jsgraph()->Constant(OpParameter<float>(node)); 328 return jsgraph()->Constant(OpParameter<float>(node));
202 default: 329 default:
203 break; 330 break;
204 } 331 }
332 if (output_rep == MachineRepresentation::kTaggedSigned ||
333 output_rep == MachineRepresentation::kTaggedPointer) {
334 // this is a no-op.
335 return node;
336 }
205 // Select the correct X -> Tagged operator. 337 // Select the correct X -> Tagged operator.
206 const Operator* op; 338 const Operator* op;
207 if (output_rep == MachineRepresentation::kNone) { 339 if (output_rep == MachineRepresentation::kNone) {
208 // We should only asisgn this representation if the type is empty. 340 // We should only asisgn this representation if the type is empty.
209 CHECK(!output_type->IsInhabited()); 341 CHECK(!output_type->IsInhabited());
210 op = machine()->ImpossibleToTagged(); 342 op = machine()->ImpossibleToTagged();
211 } else if (output_rep == MachineRepresentation::kBit) { 343 } else if (output_rep == MachineRepresentation::kBit) {
212 if (output_type->Is(Type::Boolean())) { 344 if (output_type->Is(Type::Boolean())) {
213 op = simplified()->ChangeBitToTagged(); 345 op = simplified()->ChangeBitToTagged();
214 } else { 346 } else {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 } else if (output_type->Is(Type::Unsigned32()) || 428 } else if (output_type->Is(Type::Unsigned32()) ||
297 truncation.IsUsedAsWord32()) { 429 truncation.IsUsedAsWord32()) {
298 // Either the output is uint32 or the uses only care about the 430 // Either the output is uint32 or the uses only care about the
299 // low 32 bits (so we can pick uint32 safely). 431 // low 32 bits (so we can pick uint32 safely).
300 432
301 // uint32 -> float64 -> float32 433 // uint32 -> float64 -> float32
302 op = machine()->ChangeUint32ToFloat64(); 434 op = machine()->ChangeUint32ToFloat64();
303 node = jsgraph()->graph()->NewNode(op, node); 435 node = jsgraph()->graph()->NewNode(op, node);
304 op = machine()->TruncateFloat64ToFloat32(); 436 op = machine()->TruncateFloat64ToFloat32();
305 } 437 }
306 } else if (output_rep == MachineRepresentation::kTagged) { 438 } else if (output_rep == MachineRepresentation::kTagged ||
439 output_rep == MachineRepresentation::kTaggedPointer) {
307 if (output_type->Is(Type::NumberOrOddball())) { 440 if (output_type->Is(Type::NumberOrOddball())) {
308 // tagged -> float64 -> float32 441 // tagged -> float64 -> float32
309 if (output_type->Is(Type::Number())) { 442 if (output_type->Is(Type::Number())) {
310 op = simplified()->ChangeTaggedToFloat64(); 443 op = simplified()->ChangeTaggedToFloat64();
311 } else { 444 } else {
312 op = simplified()->TruncateTaggedToFloat64(); 445 op = simplified()->TruncateTaggedToFloat64();
313 } 446 }
314 node = jsgraph()->graph()->NewNode(op, node); 447 node = jsgraph()->graph()->NewNode(op, node);
315 op = machine()->TruncateFloat64ToFloat32(); 448 op = machine()->TruncateFloat64ToFloat32();
316 } 449 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 if (output_type->Is(Type::Signed32())) { 493 if (output_type->Is(Type::Signed32())) {
361 op = machine()->ChangeInt32ToFloat64(); 494 op = machine()->ChangeInt32ToFloat64();
362 } else if (output_type->Is(Type::Unsigned32()) || 495 } else if (output_type->Is(Type::Unsigned32()) ||
363 use_info.truncation().IsUsedAsWord32()) { 496 use_info.truncation().IsUsedAsWord32()) {
364 // Either the output is uint32 or the uses only care about the 497 // Either the output is uint32 or the uses only care about the
365 // low 32 bits (so we can pick uint32 safely). 498 // low 32 bits (so we can pick uint32 safely).
366 op = machine()->ChangeUint32ToFloat64(); 499 op = machine()->ChangeUint32ToFloat64();
367 } 500 }
368 } else if (output_rep == MachineRepresentation::kBit) { 501 } else if (output_rep == MachineRepresentation::kBit) {
369 op = machine()->ChangeUint32ToFloat64(); 502 op = machine()->ChangeUint32ToFloat64();
370 } else if (output_rep == MachineRepresentation::kTagged) { 503 } else if (output_rep == MachineRepresentation::kTagged ||
504 output_rep == MachineRepresentation::kTaggedSigned ||
505 output_rep == MachineRepresentation::kTaggedPointer) {
371 if (output_type->Is(Type::Undefined())) { 506 if (output_type->Is(Type::Undefined())) {
372 return jsgraph()->Float64Constant( 507 return jsgraph()->Float64Constant(
373 std::numeric_limits<double>::quiet_NaN()); 508 std::numeric_limits<double>::quiet_NaN());
374 } else if (output_type->Is(Type::TaggedSigned())) { 509 } else if (output_type->Is(Type::TaggedSigned())) {
375 node = InsertChangeTaggedSignedToInt32(node); 510 node = InsertChangeTaggedSignedToInt32(node);
376 op = machine()->ChangeInt32ToFloat64(); 511 op = machine()->ChangeInt32ToFloat64();
377 } else if (output_type->Is(Type::Number())) { 512 } else if (output_type->Is(Type::Number())) {
378 op = simplified()->ChangeTaggedToFloat64(); 513 op = simplified()->ChangeTaggedToFloat64();
379 } else if (output_type->Is(Type::NumberOrOddball())) { 514 } else if (output_type->Is(Type::NumberOrOddball())) {
380 // TODO(jarin) Here we should check that truncation is Number. 515 // TODO(jarin) Here we should check that truncation is Number.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 op = machine()->ChangeFloat64ToInt32(); 598 op = machine()->ChangeFloat64ToInt32();
464 } else if (use_info.truncation().IsUsedAsWord32()) { 599 } else if (use_info.truncation().IsUsedAsWord32()) {
465 op = machine()->TruncateFloat64ToWord32(); 600 op = machine()->TruncateFloat64ToWord32();
466 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall || 601 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
467 use_info.type_check() == TypeCheckKind::kSigned32) { 602 use_info.type_check() == TypeCheckKind::kSigned32) {
468 op = simplified()->CheckedFloat64ToInt32( 603 op = simplified()->CheckedFloat64ToInt32(
469 output_type->Maybe(Type::MinusZero()) 604 output_type->Maybe(Type::MinusZero())
470 ? CheckForMinusZeroMode::kCheckForMinusZero 605 ? CheckForMinusZeroMode::kCheckForMinusZero
471 : CheckForMinusZeroMode::kDontCheckForMinusZero); 606 : CheckForMinusZeroMode::kDontCheckForMinusZero);
472 } 607 }
473 } else if (output_rep == MachineRepresentation::kTagged) { 608 } else if (output_rep == MachineRepresentation::kTaggedSigned) {
474 if (output_type->Is(Type::TaggedSigned())) { 609 if (output_type->Is(Type::Unsigned32())) {
610 op = simplified()->ChangeTaggedToUint32();
Jarin 2016/08/25 05:52:05 I am thinking we do not need the Unsigned case her
mvstanton 2016/08/29 12:02:10 Done.
611 } else if (output_type->Is(Type::Signed32())) {
475 op = simplified()->ChangeTaggedSignedToInt32(); 612 op = simplified()->ChangeTaggedSignedToInt32();
476 } else if (output_type->Is(Type::Unsigned32())) { 613 } else if (use_info.truncation().IsUsedAsWord32()) {
614 if (use_info.type_check() != TypeCheckKind::kNone) {
615 op = simplified()->CheckedTruncateTaggedToWord32();
616 } else {
617 op = simplified()->TruncateTaggedToWord32();
618 }
619 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
Jarin 2016/08/25 05:52:05 We already have a Smi, so we should not even get h
mvstanton 2016/08/29 12:02:10 Done.
620 op = simplified()->CheckedTaggedSignedToInt32();
621 } else if (use_info.type_check() == TypeCheckKind::kSigned32) {
622 op = simplified()->CheckedTaggedToInt32(
623 output_type->Maybe(Type::MinusZero())
624 ? CheckForMinusZeroMode::kCheckForMinusZero
625 : CheckForMinusZeroMode::kDontCheckForMinusZero);
626 }
627 } else if (output_rep == MachineRepresentation::kTagged ||
628 output_rep == MachineRepresentation::kTaggedPointer) {
629 if (output_type->Is(Type::Unsigned32())) {
477 op = simplified()->ChangeTaggedToUint32(); 630 op = simplified()->ChangeTaggedToUint32();
478 } else if (output_type->Is(Type::Signed32())) { 631 } else if (output_type->Is(Type::Signed32())) {
479 op = simplified()->ChangeTaggedToInt32(); 632 op = simplified()->ChangeTaggedToInt32();
480 } else if (use_info.truncation().IsUsedAsWord32()) { 633 } else if (use_info.truncation().IsUsedAsWord32()) {
481 if (use_info.type_check() != TypeCheckKind::kNone) { 634 if (use_info.type_check() != TypeCheckKind::kNone) {
482 op = simplified()->CheckedTruncateTaggedToWord32(); 635 op = simplified()->CheckedTruncateTaggedToWord32();
483 } else { 636 } else {
484 op = simplified()->TruncateTaggedToWord32(); 637 op = simplified()->TruncateTaggedToWord32();
485 } 638 }
486 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 639 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 } 701 }
549 default: 702 default:
550 break; 703 break;
551 } 704 }
552 // Select the correct X -> Bit operator. 705 // Select the correct X -> Bit operator.
553 const Operator* op; 706 const Operator* op;
554 if (output_rep == MachineRepresentation::kNone) { 707 if (output_rep == MachineRepresentation::kNone) {
555 // We should only use kNone representation if the type is empty. 708 // We should only use kNone representation if the type is empty.
556 CHECK(!output_type->IsInhabited()); 709 CHECK(!output_type->IsInhabited());
557 op = machine()->ImpossibleToBit(); 710 op = machine()->ImpossibleToBit();
558 } else if (output_rep == MachineRepresentation::kTagged) { 711 } else if (output_rep == MachineRepresentation::kTagged ||
712 output_rep == MachineRepresentation::kTaggedSigned ||
713 output_rep == MachineRepresentation::kTaggedPointer) {
559 op = simplified()->ChangeTaggedToBit(); 714 op = simplified()->ChangeTaggedToBit();
560 } else { 715 } else {
561 return TypeError(node, output_rep, output_type, 716 return TypeError(node, output_rep, output_type,
562 MachineRepresentation::kBit); 717 MachineRepresentation::kBit);
563 } 718 }
564 return jsgraph()->graph()->NewNode(op, node); 719 return jsgraph()->graph()->NewNode(op, node);
565 } 720 }
566 721
567 Node* RepresentationChanger::GetWord64RepresentationFor( 722 Node* RepresentationChanger::GetWord64RepresentationFor(
568 Node* node, MachineRepresentation output_rep, Type* output_type) { 723 Node* node, MachineRepresentation output_rep, Type* output_type) {
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 } 976 }
822 977
823 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { 978 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
824 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), 979 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
825 node); 980 node);
826 } 981 }
827 982
828 } // namespace compiler 983 } // namespace compiler
829 } // namespace internal 984 } // namespace internal
830 } // namespace v8 985 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698