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

Side by Side Diff: src/x64/codegen-x64.cc

Issue 149004: X64 implementation: Add some inline runtime functions. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 6 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 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 1477 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 // frame. 1488 // frame.
1489 frame_->PushElementAt(target.size() - 1); 1489 frame_->PushElementAt(target.size() - 1);
1490 // Result ignored = frame_->CallRuntime(Runtime::kToSlowProperties, 1); 1490 // Result ignored = frame_->CallRuntime(Runtime::kToSlowProperties, 1);
1491 } 1491 }
1492 if (node->op() == Token::ASSIGN || 1492 if (node->op() == Token::ASSIGN ||
1493 node->op() == Token::INIT_VAR || 1493 node->op() == Token::INIT_VAR ||
1494 node->op() == Token::INIT_CONST) { 1494 node->op() == Token::INIT_CONST) {
1495 Load(node->value()); 1495 Load(node->value());
1496 1496
1497 } else { 1497 } else {
1498 // TODO(X64): Make compound assignments work.
1499 /*
1500 Literal* literal = node->value()->AsLiteral(); 1498 Literal* literal = node->value()->AsLiteral();
1501 bool overwrite_value = 1499 bool overwrite_value =
1502 (node->value()->AsBinaryOperation() != NULL && 1500 (node->value()->AsBinaryOperation() != NULL &&
1503 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 1501 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
1504 Variable* right_var = node->value()->AsVariableProxy()->AsVariable(); 1502 Variable* right_var = node->value()->AsVariableProxy()->AsVariable();
1505 // There are two cases where the target is not read in the right hand 1503 // There are two cases where the target is not read in the right hand
1506 // side, that are easy to test for: the right hand side is a literal, 1504 // side, that are easy to test for: the right hand side is a literal,
1507 // or the right hand side is a different variable. TakeValue invalidates 1505 // or the right hand side is a different variable. TakeValue invalidates
1508 // the target, with an implicit promise that it will be written to again 1506 // the target, with an implicit promise that it will be written to again
1509 // before it is read. 1507 // before it is read.
1510 if (literal != NULL || (right_var != NULL && right_var != var)) { 1508 // TODO(X64): Implement TakeValue optimization.
1511 target.TakeValue(NOT_INSIDE_TYPEOF); 1509 if (false && literal != NULL || (right_var != NULL && right_var != var)) {
1510 // target.TakeValue(NOT_INSIDE_TYPEOF);
1512 } else { 1511 } else {
1513 target.GetValue(NOT_INSIDE_TYPEOF); 1512 target.GetValue(NOT_INSIDE_TYPEOF);
1514 } 1513 }
1515 */
1516 Load(node->value()); 1514 Load(node->value());
1517 /*
1518 GenericBinaryOperation(node->binary_op(), 1515 GenericBinaryOperation(node->binary_op(),
1519 node->type(), 1516 node->type(),
1520 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); 1517 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
1521 */
1522 } 1518 }
1523 1519
1524 if (var != NULL && 1520 if (var != NULL &&
1525 var->mode() == Variable::CONST && 1521 var->mode() == Variable::CONST &&
1526 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { 1522 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
1527 // Assignment ignored - leave the value on the stack. 1523 // Assignment ignored - leave the value on the stack.
1528 } else { 1524 } else {
1529 CodeForSourcePosition(node->position()); 1525 CodeForSourcePosition(node->position());
1530 if (node->op() == Token::INIT_CONST) { 1526 if (node->op() == Token::INIT_CONST) {
1531 // Dynamic constant initializations must use the function context 1527 // Dynamic constant initializations must use the function context
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after
2268 Comparison(cc, strict, destination()); 2264 Comparison(cc, strict, destination());
2269 } 2265 }
2270 2266
2271 2267
2272 void CodeGenerator::VisitThisFunction(ThisFunction* node) { 2268 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
2273 frame_->PushFunction(); 2269 frame_->PushFunction();
2274 } 2270 }
2275 2271
2276 2272
2277 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { 2273 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) {
2278 UNIMPLEMENTED(); 2274 ASSERT(args->length() == 1);
2275
2276 // ArgumentsAccessStub expects the key in edx and the formal
2277 // parameter count in eax.
Lasse Reichstein 2009/06/25 11:54:59 rdx * 2
2278 Load(args->at(0));
2279 Result key = frame_->Pop();
2280 // Explicitly create a constant result.
2281 Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters())));
2282 // Call the shared stub to get to arguments[key].
2283 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
2284 Result result = frame_->CallStub(&stub, &key, &count);
2285 frame_->Push(&result);
2279 } 2286 }
2280 2287
2288
2289 void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
2290 ASSERT(args->length() == 1);
2291 Load(args->at(0));
2292 Result value = frame_->Pop();
2293 value.ToRegister();
2294 ASSERT(value.is_valid());
2295 __ testl(value.reg(), Immediate(kSmiTagMask));
2296 destination()->false_target()->Branch(equal);
2297 // It is a heap object - get map.
2298 // Check if the object is a JS array or not.
2299 __ CmpObjectType(value.reg(), JS_ARRAY_TYPE, kScratchRegister);
2300 value.Unuse();
2301 destination()->Split(equal);
2302 }
2303
2304
2281 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { 2305 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) {
2282 UNIMPLEMENTED();} 2306 ASSERT(args->length() == 0);
2307 // ArgumentsAccessStub takes the parameter count as an input argument
2308 // in register eax. Create a constant result for it.
Lasse Reichstein 2009/06/25 11:54:59 rax
2309 Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters())));
2310 // Call the shared stub to get to the arguments.length.
2311 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH);
2312 Result result = frame_->CallStub(&stub, &count);
2313 frame_->Push(&result);
2314 }
2315
2283 2316
2284 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* a) { 2317 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* a) {
2285 UNIMPLEMENTED(); 2318 UNIMPLEMENTED();
2286 } 2319 }
2287 2320
2288 void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
2289 UNIMPLEMENTED();
2290 }
2291 2321
2292 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { 2322 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
2293 UNIMPLEMENTED(); 2323 UNIMPLEMENTED();
2294 } 2324 }
2295 2325
2326
2296 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { 2327 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
2297 UNIMPLEMENTED(); 2328 ASSERT(args->length() == 1);
2329 Load(args->at(0));
2330 Result value = frame_->Pop();
2331 value.ToRegister();
2332 ASSERT(value.is_valid());
2333 __ testl(value.reg(), Immediate(kSmiTagMask));
2334 value.Unuse();
2335 destination()->Split(zero);
2298 } 2336 }
2299 2337
2338
2300 void CodeGenerator::GenerateLog(ZoneList<Expression*>* a) { 2339 void CodeGenerator::GenerateLog(ZoneList<Expression*>* a) {
2301 UNIMPLEMENTED(); 2340 UNIMPLEMENTED();
2302 } 2341 }
2303 2342
2304 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { 2343 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
2305 UNIMPLEMENTED(); 2344 ASSERT(args->length() == 2);
2345
2346 // Load the two objects into registers and perform the comparison.
2347 Load(args->at(0));
2348 Load(args->at(1));
2349 Result right = frame_->Pop();
2350 Result left = frame_->Pop();
2351 right.ToRegister();
2352 left.ToRegister();
2353 __ cmpq(right.reg(), left.reg());
2354 right.Unuse();
2355 left.Unuse();
2356 destination()->Split(equal);
2306 } 2357 }
2307 2358
2359
2360
2308 void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* a) { 2361 void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* a) {
2309 UNIMPLEMENTED(); 2362 UNIMPLEMENTED();
2310 } 2363 }
2311 2364
2312 void CodeGenerator::GenerateFastMathOp(MathOp op, ZoneList<Expression*>* args) { 2365 void CodeGenerator::GenerateFastMathOp(MathOp op, ZoneList<Expression*>* args) {
2313 UNIMPLEMENTED(); 2366 UNIMPLEMENTED();
2314 } 2367 }
2315 2368
2369
2316 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) { 2370 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) {
2317 UNIMPLEMENTED(); 2371 ASSERT(args->length() == 2);
2372 JumpTarget leave;
2373 Load(args->at(0)); // Load the object.
2374 Load(args->at(1)); // Load the value.
2375 Result value = frame_->Pop();
2376 Result object = frame_->Pop();
2377 value.ToRegister();
2378 object.ToRegister();
2379
2380 // if (object->IsSmi()) return value.
2381 __ testl(object.reg(), Immediate(kSmiTagMask));
2382 leave.Branch(zero, &value);
2383
2384 // It is a heap object - get its map.
2385 Result scratch = allocator_->Allocate();
2386 ASSERT(scratch.is_valid());
2387 // if (!object->IsJSValue()) return value.
2388 __ CmpObjectType(object.reg(), JS_VALUE_TYPE, scratch.reg());
2389 leave.Branch(not_equal, &value);
2390
2391 // Store the value.
2392 __ movq(FieldOperand(object.reg(), JSValue::kValueOffset), value.reg());
2393 // Update the write barrier. Save the value as it will be
2394 // overwritten by the write barrier code and is needed afterward.
2395 Result duplicate_value = allocator_->Allocate();
2396 ASSERT(duplicate_value.is_valid());
2397 __ movq(duplicate_value.reg(), value.reg());
2398 // The object register is also overwritten by the write barrier and
2399 // possibly aliased in the frame.
2400 frame_->Spill(object.reg());
2401 __ RecordWrite(object.reg(), JSValue::kValueOffset, duplicate_value.reg(),
2402 scratch.reg());
2403 object.Unuse();
2404 scratch.Unuse();
2405 duplicate_value.Unuse();
2406
2407 // Leave.
2408 leave.Bind(&value);
2409 frame_->Push(&value);
2318 } 2410 }
2319 2411
2412
2320 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { 2413 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) {
2321 UNIMPLEMENTED(); 2414 UNIMPLEMENTED();
2322 } 2415 }
2323 2416
2324 // ----------------------------------------------------------------------------- 2417 // -----------------------------------------------------------------------------
2325 // CodeGenerator implementation of Expressions 2418 // CodeGenerator implementation of Expressions
2326 2419
2327 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { 2420 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) {
2328 #ifdef DEBUG 2421 #ifdef DEBUG
2329 int original_height = frame_->height(); 2422 int original_height = frame_->height();
(...skipping 3173 matching lines...) Expand 10 before | Expand all | Expand 10 after
5503 break; 5596 break;
5504 default: 5597 default:
5505 UNREACHABLE(); 5598 UNREACHABLE();
5506 } 5599 }
5507 } 5600 }
5508 5601
5509 5602
5510 #undef __ 5603 #undef __
5511 5604
5512 } } // namespace v8::internal 5605 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698